Yuki Takei 1 год назад
Родитель
Сommit
0ed54b520e
95 измененных файлов с 747 добавлено и 747 удалено
  1. 5 5
      apps/app/src/features/external-user-group/server/routes/apiv3/external-user-group.ts
  2. 6 6
      apps/app/src/features/external-user-group/server/service/keycloak-user-group-sync.ts
  3. 4 4
      apps/app/src/features/external-user-group/server/service/ldap-user-group-sync.ts
  4. 2 2
      apps/app/src/features/openai/server/routes/middlewares/certify-ai-service.ts
  5. 4 4
      apps/app/src/features/openai/server/services/assistant/assistant.ts
  6. 1 1
      apps/app/src/features/openai/server/services/client-delegator/openai-client-delegator.ts
  7. 4 4
      apps/app/src/features/openai/server/services/cron/thread-deletion-cron.ts
  8. 4 4
      apps/app/src/features/openai/server/services/cron/vector-store-file-deletion-cron.ts
  9. 1 1
      apps/app/src/features/openai/server/services/is-ai-enabled.ts
  10. 3 3
      apps/app/src/features/openai/server/services/openai.ts
  11. 3 3
      apps/app/src/features/opentelemetry/server/start.ts
  12. 5 5
      apps/app/src/features/questionnaire/server/service/questionnaire.ts
  13. 31 31
      apps/app/src/pages/[[...path]].page.tsx
  14. 17 17
      apps/app/src/pages/_private-legacy-pages.page.tsx
  15. 18 18
      apps/app/src/pages/_search.page.tsx
  16. 1 1
      apps/app/src/pages/admin/ai-integration.page.tsx
  17. 2 2
      apps/app/src/pages/admin/audit-log.page.tsx
  18. 1 1
      apps/app/src/pages/admin/customize.page.tsx
  19. 1 1
      apps/app/src/pages/admin/data-transfer.page.tsx
  20. 2 2
      apps/app/src/pages/admin/index.page.tsx
  21. 1 1
      apps/app/src/pages/installer.page.tsx
  22. 11 11
      apps/app/src/pages/login/index.page.tsx
  23. 18 18
      apps/app/src/pages/me/[[...path]].page.tsx
  24. 19 19
      apps/app/src/pages/share/[[...path]].page.tsx
  25. 3 3
      apps/app/src/pages/tags.page.tsx
  26. 4 4
      apps/app/src/pages/trash.page.tsx
  27. 2 2
      apps/app/src/pages/user-activation.page.tsx
  28. 5 5
      apps/app/src/pages/utils/commons.ts
  29. 3 3
      apps/app/src/server/crowi/express-init.js
  30. 10 10
      apps/app/src/server/crowi/index.js
  31. 1 1
      apps/app/src/server/middlewares/certify-shared-page-attachment/validate-referer/retrieve-site-url.ts
  32. 1 1
      apps/app/src/server/middlewares/exclude-read-only-user.ts
  33. 2 2
      apps/app/src/server/models/obsolete-page.js
  34. 2 2
      apps/app/src/server/models/slack-app-integration.js
  35. 8 8
      apps/app/src/server/models/user.js
  36. 2 2
      apps/app/src/server/routes/apiv3/admin-home.ts
  37. 72 72
      apps/app/src/server/routes/apiv3/app-settings.js
  38. 1 1
      apps/app/src/server/routes/apiv3/attachment.js
  39. 41 41
      apps/app/src/server/routes/apiv3/customize-setting.js
  40. 3 3
      apps/app/src/server/routes/apiv3/forgot-password.js
  41. 5 5
      apps/app/src/server/routes/apiv3/import.js
  42. 2 2
      apps/app/src/server/routes/apiv3/index.js
  43. 1 1
      apps/app/src/server/routes/apiv3/installer.ts
  44. 16 16
      apps/app/src/server/routes/apiv3/markdown-setting.js
  45. 5 5
      apps/app/src/server/routes/apiv3/notification-setting.js
  46. 2 2
      apps/app/src/server/routes/apiv3/page-listing.ts
  47. 1 1
      apps/app/src/server/routes/apiv3/page/create-page.ts
  48. 1 1
      apps/app/src/server/routes/apiv3/page/index.ts
  49. 4 4
      apps/app/src/server/routes/apiv3/pages/index.js
  50. 2 2
      apps/app/src/server/routes/apiv3/personal-setting.js
  51. 1 1
      apps/app/src/server/routes/apiv3/revisions.js
  52. 120 120
      apps/app/src/server/routes/apiv3/security-settings/index.js
  53. 1 1
      apps/app/src/server/routes/apiv3/share-links.js
  54. 6 6
      apps/app/src/server/routes/apiv3/slack-integration-legacy-settings.js
  55. 13 13
      apps/app/src/server/routes/apiv3/slack-integration-settings.js
  56. 4 4
      apps/app/src/server/routes/apiv3/slack-integration.js
  57. 1 1
      apps/app/src/server/routes/apiv3/staffs.js
  58. 6 6
      apps/app/src/server/routes/apiv3/user-activation.ts
  59. 5 5
      apps/app/src/server/routes/apiv3/users.js
  60. 1 1
      apps/app/src/server/routes/forgot-password.ts
  61. 10 10
      apps/app/src/server/routes/login-passport.js
  62. 3 3
      apps/app/src/server/routes/login.js
  63. 2 2
      apps/app/src/server/routes/ogp.ts
  64. 10 10
      apps/app/src/server/service/acl.integ.ts
  65. 4 4
      apps/app/src/server/service/acl.ts
  66. 5 5
      apps/app/src/server/service/activity.ts
  67. 6 6
      apps/app/src/server/service/app.ts
  68. 5 5
      apps/app/src/server/service/customize.ts
  69. 16 16
      apps/app/src/server/service/file-uploader/aws.ts
  70. 11 11
      apps/app/src/server/service/file-uploader/azure.ts
  71. 5 5
      apps/app/src/server/service/file-uploader/file-uploader.ts
  72. 10 10
      apps/app/src/server/service/file-uploader/gcs.ts
  73. 1 1
      apps/app/src/server/service/file-uploader/gridfs.ts
  74. 1 1
      apps/app/src/server/service/file-uploader/index.ts
  75. 4 4
      apps/app/src/server/service/file-uploader/local.ts
  76. 12 12
      apps/app/src/server/service/g2g-transfer.ts
  77. 1 1
      apps/app/src/server/service/global-notification/global-notification-mail.js
  78. 2 2
      apps/app/src/server/service/global-notification/index.js
  79. 1 1
      apps/app/src/server/service/i18next.ts
  80. 1 1
      apps/app/src/server/service/import/import.ts
  81. 2 2
      apps/app/src/server/service/ldap.ts
  82. 10 10
      apps/app/src/server/service/mail.ts
  83. 1 1
      apps/app/src/server/service/page/delete-completely-user-home-by-system.integ.ts
  84. 12 12
      apps/app/src/server/service/page/index.ts
  85. 1 1
      apps/app/src/server/service/page/should-use-v4-process.ts
  86. 49 49
      apps/app/src/server/service/passport.ts
  87. 4 4
      apps/app/src/server/service/rest-qiita-API.js
  88. 2 2
      apps/app/src/server/service/s2s-messaging/index.ts
  89. 4 4
      apps/app/src/server/service/s2s-messaging/nchan.ts
  90. 9 9
      apps/app/src/server/service/search-delegator/elasticsearch.ts
  91. 1 1
      apps/app/src/server/service/search.ts
  92. 8 8
      apps/app/src/server/service/slack-integration.ts
  93. 3 3
      apps/app/src/server/service/socket-io/socket-io.ts
  94. 3 3
      apps/app/src/server/util/importer.js
  95. 7 7
      apps/app/src/server/util/slack-legacy.ts

+ 5 - 5
apps/app/src/features/external-user-group/server/routes/apiv3/external-user-group.ts

@@ -319,7 +319,7 @@ module.exports = (crowi: Crowi): Router => {
       );
     }
 
-    const isLdapEnabled = await configManager.getConfig('crowi', 'security:passport-ldap:isEnabled');
+    const isLdapEnabled = await configManager.getConfig('security:passport-ldap:isEnabled');
     if (!isLdapEnabled) {
       return res.apiv3Err(
         new ErrorV3('Authentication using ldap is not set', 'external_user_group.ldap.auth_not_set'), 422,
@@ -359,13 +359,13 @@ module.exports = (crowi: Crowi): Router => {
       // see: https://regex101.com/r/3ihDmf/1
       const regex = new RegExp(`^${kcHost}/.*/${kcGroupRealm}(/|$).*`);
 
-      const isOidcEnabled = configManager.getConfig('crowi', 'security:passport-oidc:isEnabled');
-      const oidcIssuerHost = configManager.getConfig('crowi', 'security:passport-oidc:issuerHost');
+      const isOidcEnabled = configManager.getConfig('security:passport-oidc:isEnabled');
+      const oidcIssuerHost = configManager.getConfig('security:passport-oidc:issuerHost');
 
       if (isOidcEnabled && oidcIssuerHost != null && regex.test(oidcIssuerHost)) return 'oidc';
 
-      const isSamlEnabled = configManager.getConfig('crowi', 'security:passport-saml:isEnabled');
-      const samlEntryPoint = configManager.getConfig('crowi', 'security:passport-saml:entryPoint');
+      const isSamlEnabled = configManager.getConfig('security:passport-saml:isEnabled');
+      const samlEntryPoint = configManager.getConfig('security:passport-saml:entryPoint');
 
       if (isSamlEnabled && samlEntryPoint != null && regex.test(samlEntryPoint)) return 'saml';
 

+ 6 - 6
apps/app/src/features/external-user-group/server/service/keycloak-user-group-sync.ts

@@ -35,10 +35,10 @@ export class KeycloakUserGroupSyncService extends ExternalUserGroupSyncService {
   }
 
   init(authProviderType: 'oidc' | 'saml'): void {
-    const kcHost = configManager.getConfig('crowi', 'external-user-group:keycloak:host');
-    const kcGroupRealm = configManager.getConfig('crowi', 'external-user-group:keycloak:groupRealm');
-    const kcGroupSyncClientRealm = configManager.getConfig('crowi', 'external-user-group:keycloak:groupSyncClientRealm');
-    const kcGroupDescriptionAttribute = configManager.getConfig('crowi', 'external-user-group:keycloak:groupDescriptionAttribute');
+    const kcHost = configManager.getConfig('external-user-group:keycloak:host');
+    const kcGroupRealm = configManager.getConfig('external-user-group:keycloak:groupRealm');
+    const kcGroupSyncClientRealm = configManager.getConfig('external-user-group:keycloak:groupSyncClientRealm');
+    const kcGroupDescriptionAttribute = configManager.getConfig('external-user-group:keycloak:groupDescriptionAttribute');
 
     this.kcAdminClient = new KeycloakAdminClient({ baseUrl: kcHost, realmName: kcGroupSyncClientRealm });
     this.realm = kcGroupRealm;
@@ -71,8 +71,8 @@ export class KeycloakUserGroupSyncService extends ExternalUserGroupSyncService {
    * Authenticate to group sync client using client credentials grant type
    */
   private async auth(): Promise<void> {
-    const kcGroupSyncClientID = configManager.getConfig('crowi', 'external-user-group:keycloak:groupSyncClientID');
-    const kcGroupSyncClientSecret = configManager.getConfig('crowi', 'external-user-group:keycloak:groupSyncClientSecret');
+    const kcGroupSyncClientID = configManager.getConfig('external-user-group:keycloak:groupSyncClientID');
+    const kcGroupSyncClientSecret = configManager.getConfig('external-user-group:keycloak:groupSyncClientSecret');
 
     await this.kcAdminClient.auth({
       grantType: 'client_credentials',

+ 4 - 4
apps/app/src/features/external-user-group/server/service/ldap-user-group-sync.ts

@@ -49,10 +49,10 @@ export class LdapUserGroupSyncService extends ExternalUserGroupSyncService {
   }
 
   override async generateExternalUserGroupTrees(): Promise<ExternalUserGroupTreeNode[]> {
-    const groupChildGroupAttribute = configManager.getConfig('crowi', 'external-user-group:ldap:groupChildGroupAttribute');
-    const groupMembershipAttribute = configManager.getConfig('crowi', 'external-user-group:ldap:groupMembershipAttribute');
-    const groupNameAttribute = configManager.getConfig('crowi', 'external-user-group:ldap:groupNameAttribute');
-    const groupDescriptionAttribute = configManager.getConfig('crowi', 'external-user-group:ldap:groupDescriptionAttribute');
+    const groupChildGroupAttribute = configManager.getConfig('external-user-group:ldap:groupChildGroupAttribute');
+    const groupMembershipAttribute = configManager.getConfig('external-user-group:ldap:groupMembershipAttribute');
+    const groupNameAttribute = configManager.getConfig('external-user-group:ldap:groupNameAttribute');
+    const groupDescriptionAttribute = configManager.getConfig('external-user-group:ldap:groupDescriptionAttribute');
     const groupBase = ldapService.getGroupSearchBase();
 
     const groupEntries = await ldapService.searchGroupDir();

+ 2 - 2
apps/app/src/features/openai/server/routes/middlewares/certify-ai-service.ts

@@ -8,7 +8,7 @@ import { OpenaiServiceTypes } from '../../../interfaces/ai';
 const logger = loggerFactory('growi:middlewares:certify-ai-service');
 
 export const certifyAiService = (req: Request, res: Response & { apiv3Err }, next: NextFunction): void => {
-  const aiEnabled = configManager.getConfig('crowi', 'app:aiEnabled');
+  const aiEnabled = configManager.getConfig('app:aiEnabled');
 
   if (!aiEnabled) {
     const message = 'AI_ENABLED is not true';
@@ -16,7 +16,7 @@ export const certifyAiService = (req: Request, res: Response & { apiv3Err }, nex
     return res.apiv3Err(message, 403);
   }
 
-  const openaiServiceType = configManager.getConfig('crowi', 'openai:serviceType');
+  const openaiServiceType = configManager.getConfig('openai:serviceType');
   if (openaiServiceType == null || !OpenaiServiceTypes.includes(openaiServiceType)) {
     const message = 'AI_SERVICE_TYPE is missing or contains an invalid value';
     logger.error(message);

+ 4 - 4
apps/app/src/features/openai/server/services/assistant/assistant.ts

@@ -22,7 +22,7 @@ const isValidChatModel = (model: string): model is OpenAI.Chat.ChatModel => {
 const getAssistantModelByType = (type: AssistantType): OpenAI.Chat.ChatModel => {
   const configValue = type === AssistantType.SEARCH
     ? undefined // TODO: add the value for 'openai:assistantModel:search' to config-definition.ts
-    : configManager.getConfig('crowi', 'openai:assistantModel:chat');
+    : configManager.getConfig('openai:assistantModel:chat');
 
   if (typeof configValue === 'string' && isValidChatModel(configValue)) {
     return configValue;
@@ -56,7 +56,7 @@ const findAssistantByName = async(assistantName: string): Promise<OpenAI.Beta.As
 };
 
 const getOrCreateAssistant = async(type: AssistantType, nameSuffix?: string): Promise<OpenAI.Beta.Assistant> => {
-  const appSiteUrl = configManager.getConfig('crowi', 'app:siteUrl');
+  const appSiteUrl = configManager.getConfig('app:siteUrl');
   const assistantName = `GROWI ${type} Assistant for ${appSiteUrl}${nameSuffix != null ? ` ${nameSuffix}` : ''}`;
   const assistantModel = getAssistantModelByType(type);
 
@@ -68,7 +68,7 @@ const getOrCreateAssistant = async(type: AssistantType, nameSuffix?: string): Pr
       }));
 
   // update instructions
-  const instructions = configManager.getConfig('crowi', 'openai:chatAssistantInstructions');
+  const instructions = configManager.getConfig('openai:chatAssistantInstructions');
   openaiClient.beta.assistants.update(assistant.id, {
     instructions,
     model: assistantModel,
@@ -86,7 +86,7 @@ const getOrCreateAssistant = async(type: AssistantType, nameSuffix?: string): Pr
 
 //   searchAssistant = await getOrCreateAssistant(AssistantType.SEARCH);
 //   openaiClient.beta.assistants.update(searchAssistant.id, {
-//     instructions: configManager.getConfig('crowi', 'openai:searchAssistantInstructions'),
+//     instructions: configManager.getConfig('openai:searchAssistantInstructions'),
 //     tools: [{ type: 'file_search' }],
 //   });
 

+ 1 - 1
apps/app/src/features/openai/server/services/client-delegator/openai-client-delegator.ts

@@ -13,7 +13,7 @@ export class OpenaiClientDelegator implements IOpenaiClientDelegator {
 
   constructor() {
     // Retrieve OpenAI related values from environment variables
-    const apiKey = configManager.getConfig('crowi', 'openai:apiKey');
+    const apiKey = configManager.getConfig('openai:apiKey');
 
     const isValid = [apiKey].every(value => value != null);
     if (!isValid) {

+ 4 - 4
apps/app/src/features/openai/server/services/cron/thread-deletion-cron.ts

@@ -37,10 +37,10 @@ export class ThreadDeletionCronService {
     }
 
     this.openaiService = openaiService;
-    this.threadDeletionCronExpression = configManager.getConfig('crowi', 'openai:threadDeletionCronExpression');
-    this.threadDeletionCronMaxMinutesUntilRequest = configManager.getConfig('crowi', 'app:openaiThreadDeletionCronMaxMinutesUntilRequest');
-    this.threadDeletionBarchSize = configManager.getConfig('crowi', 'openai:threadDeletionBarchSize');
-    this.threadDeletionApiCallInterval = configManager.getConfig('crowi', 'openai:threadDeletionApiCallInterval');
+    this.threadDeletionCronExpression = configManager.getConfig('openai:threadDeletionCronExpression');
+    this.threadDeletionCronMaxMinutesUntilRequest = configManager.getConfig('app:openaiThreadDeletionCronMaxMinutesUntilRequest');
+    this.threadDeletionBarchSize = configManager.getConfig('openai:threadDeletionBarchSize');
+    this.threadDeletionApiCallInterval = configManager.getConfig('openai:threadDeletionApiCallInterval');
 
     this.cronJob?.stop();
     this.cronJob = this.generateCronJob();

+ 4 - 4
apps/app/src/features/openai/server/services/cron/vector-store-file-deletion-cron.ts

@@ -36,10 +36,10 @@ export class VectorStoreFileDeletionCronService {
     }
 
     this.openaiService = openaiService;
-    this.vectorStoreFileDeletionCronExpression = configManager.getConfig('crowi', 'openai:vectorStoreFileDeletionCronExpression');
-    this.vectorStoreFileDeletionCronMaxMinutesUntilRequest = configManager.getConfig('crowi', 'app:openaiVectorStoreFileDeletionCronMaxMinutesUntilRequest');
-    this.vectorStoreFileDeletionBarchSize = configManager.getConfig('crowi', 'openai:vectorStoreFileDeletionBarchSize');
-    this.vectorStoreFileDeletionApiCallInterval = configManager.getConfig('crowi', 'openai:vectorStoreFileDeletionApiCallInterval');
+    this.vectorStoreFileDeletionCronExpression = configManager.getConfig('openai:vectorStoreFileDeletionCronExpression');
+    this.vectorStoreFileDeletionCronMaxMinutesUntilRequest = configManager.getConfig('app:openaiVectorStoreFileDeletionCronMaxMinutesUntilRequest');
+    this.vectorStoreFileDeletionBarchSize = configManager.getConfig('openai:vectorStoreFileDeletionBarchSize');
+    this.vectorStoreFileDeletionApiCallInterval = configManager.getConfig('openai:vectorStoreFileDeletionApiCallInterval');
 
     this.cronJob?.stop();
     this.cronJob = this.generateCronJob();

+ 1 - 1
apps/app/src/features/openai/server/services/is-ai-enabled.ts

@@ -1,3 +1,3 @@
 import { configManager } from '~/server/service/config-manager';
 
-export const isAiEnabled = (): boolean => configManager.getConfig('crowi', 'app:aiEnabled');
+export const isAiEnabled = (): boolean => configManager.getConfig('app:aiEnabled');

+ 3 - 3
apps/app/src/features/openai/server/services/openai.ts

@@ -49,7 +49,7 @@ export interface IOpenaiService {
 class OpenaiService implements IOpenaiService {
 
   private get client() {
-    const openaiServiceType = configManager.getConfig('crowi', 'openai:serviceType');
+    const openaiServiceType = configManager.getConfig('openai:serviceType');
     return getClient({ openaiServiceType });
   }
 
@@ -363,8 +363,8 @@ export const getOpenaiService = (): IOpenaiService | undefined => {
     return instance;
   }
 
-  const aiEnabled = configManager.getConfig('crowi', 'app:aiEnabled');
-  const openaiServiceType = configManager.getConfig('crowi', 'openai:serviceType');
+  const aiEnabled = configManager.getConfig('app:aiEnabled');
+  const openaiServiceType = configManager.getConfig('openai:serviceType');
   if (aiEnabled && openaiServiceType != null && OpenaiServiceTypes.includes(openaiServiceType)) {
     instance = new OpenaiService();
     return instance;

+ 3 - 3
apps/app/src/features/opentelemetry/server/start.ts

@@ -14,7 +14,7 @@ let sdkInstance: NodeSDK;
  * Since otel library sees it.
  */
 function overwriteSdkDisabled(): void {
-  const instrumentationEnabled = configManager.getConfig('crowi', 'otel:enabled');
+  const instrumentationEnabled = configManager.getConfig('otel:enabled');
 
   if (instrumentationEnabled && (
     process.env.OTEL_SDK_DISABLED === 'true'
@@ -44,7 +44,7 @@ export const startInstrumentation = async(version: string): Promise<void> => {
 
   overwriteSdkDisabled();
 
-  const instrumentationEnabled = configManager.getConfig('crowi', 'otel:enabled');
+  const instrumentationEnabled = configManager.getConfig('otel:enabled');
   if (instrumentationEnabled) {
 
     logger.info(`GROWI now collects anonymous telemetry.
@@ -65,7 +65,7 @@ For more information, see https://docs.growi.org/en/admin-guide/telemetry.html.
     const { NodeSDK } = await import('@opentelemetry/sdk-node');
     const { generateNodeSDKConfiguration } = await import('./node-sdk-configuration');
 
-    const serviceInstanceId = configManager.getConfig('crowi', 'otel:serviceInstanceId')
+    const serviceInstanceId = configManager.getConfig('otel:serviceInstanceId')
       ?? 'generated-appSiteUrlHashed'; // TODO: generated appSiteUrlHashed
 
     sdkInstance = new NodeSDK(generateNodeSDKConfiguration(serviceInstanceId, version));

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

@@ -59,16 +59,16 @@ class QuestionnaireService {
     const wikiType = isGuestAllowedToRead ? GrowiWikiType.open : GrowiWikiType.closed;
 
     const activeExternalAccountTypes: GrowiExternalAuthProviderType[] = Object.values(GrowiExternalAuthProviderType).filter((type) => {
-      return this.crowi.configManager.getConfig('crowi', `security:passport-${type}:isEnabled`);
+      return this.crowi.configManager.getConfig(`security:passport-${type}:isEnabled`);
     });
 
-    const typeStr = this.crowi.configManager.getConfig('crowi', 'app:serviceType');
+    const typeStr = this.crowi.configManager.getConfig('app:serviceType');
     const type = Object.values(GrowiServiceType).includes(typeStr) ? typeStr : null;
 
-    const attachmentTypeStr = this.crowi.configManager.getConfig('crowi', 'app:fileUploadType');
+    const attachmentTypeStr = this.crowi.configManager.getConfig('app:fileUploadType');
     const attachmentType = Object.values(AttachmentMethodType).includes(attachmentTypeStr) ? attachmentTypeStr : null;
 
-    const deploymentTypeStr = this.crowi.configManager.getConfig('crowi', 'app:deploymentType');
+    const deploymentTypeStr = this.crowi.configManager.getConfig('app:deploymentType');
     const deploymentType = Object.values(GrowiDeploymentType).includes(deploymentTypeStr) ? deploymentTypeStr : null;
 
     return {
@@ -79,7 +79,7 @@ class QuestionnaireService {
         arch: os.arch(),
         totalmem: os.totalmem(),
       },
-      appSiteUrl: this.crowi.configManager.getConfig('crowi', 'questionnaire:isAppSiteUrlHashed') ? null : appSiteUrl,
+      appSiteUrl: this.crowi.configManager.getConfig('questionnaire:isAppSiteUrlHashed') ? null : appSiteUrl,
       appSiteUrlHashed,
       installedAt,
       installedAtByOldestUser,

+ 31 - 31
apps/app/src/pages/[[...path]].page.tsx

@@ -486,7 +486,7 @@ async function injectPageData(context: GetServerSidePropsContext, props: Props):
   if (page != null) {
     page.initLatestRevisionField(revisionId);
     props.isLatestRevision = page.isLatestRevision();
-    const ssrMaxRevisionBodyLength = configManager.getConfig('crowi', 'app:ssrMaxRevisionBodyLength');
+    const ssrMaxRevisionBodyLength = configManager.getConfig('app:ssrMaxRevisionBodyLength');
     props.skipSSR = await skipSSR(page, ssrMaxRevisionBodyLength);
     populated = await page.populateDataToShowRevision(props.skipSSR); // shouldExcludeBody = skipSSR
   }
@@ -560,62 +560,62 @@ function injectServerConfigurations(context: GetServerSidePropsContext, props: P
     slackIntegrationService, passportService,
   } = crowi;
 
-  props.aiEnabled = configManager.getConfig('crowi', 'app:aiEnabled');
+  props.aiEnabled = configManager.getConfig('app:aiEnabled');
 
   props.isSearchServiceConfigured = searchService.isConfigured;
   props.isSearchServiceReachable = searchService.isReachable;
-  props.isSearchScopeChildrenAsDefault = configManager.getConfig('crowi', 'customize:isSearchScopeChildrenAsDefault');
-  props.elasticsearchMaxBodyLengthToIndex = configManager.getConfig('crowi', 'app:elasticsearchMaxBodyLengthToIndex');
+  props.isSearchScopeChildrenAsDefault = configManager.getConfig('customize:isSearchScopeChildrenAsDefault');
+  props.elasticsearchMaxBodyLengthToIndex = configManager.getConfig('app:elasticsearchMaxBodyLengthToIndex');
 
-  props.isRomUserAllowedToComment = configManager.getConfig('crowi', 'security:isRomUserAllowedToComment');
+  props.isRomUserAllowedToComment = configManager.getConfig('security:isRomUserAllowedToComment');
 
   props.isSlackConfigured = slackIntegrationService.isSlackConfigured;
   // props.isMailerSetup = mailService.isMailerSetup;
   props.isAclEnabled = aclService.isAclEnabled();
   // props.hasSlackConfig = slackNotificationService.hasSlackConfig();
-  props.drawioUri = configManager.getConfig('crowi', 'app:drawioUri');
-  // props.highlightJsStyle = configManager.getConfig('crowi', 'customize:highlightJsStyle');
-  props.isAllReplyShown = configManager.getConfig('crowi', 'customize:isAllReplyShown');
-  props.isContainerFluid = configManager.getConfig('crowi', 'customize:isContainerFluid');
-  props.isEnabledStaleNotification = configManager.getConfig('crowi', 'customize:isEnabledStaleNotification');
-  props.disableLinkSharing = configManager.getConfig('crowi', 'security:disableLinkSharing');
+  props.drawioUri = configManager.getConfig('app:drawioUri');
+  // props.highlightJsStyle = configManager.getConfig('customize:highlightJsStyle');
+  props.isAllReplyShown = configManager.getConfig('customize:isAllReplyShown');
+  props.isContainerFluid = configManager.getConfig('customize:isContainerFluid');
+  props.isEnabledStaleNotification = configManager.getConfig('customize:isEnabledStaleNotification');
+  props.disableLinkSharing = configManager.getConfig('security:disableLinkSharing');
   props.isUploadAllFileAllowed = fileUploadService.getFileUploadEnabled();
   props.isUploadEnabled = fileUploadService.getIsUploadable();
 
   props.isLocalAccountRegistrationEnabled = passportService.isLocalStrategySetup
-  && configManager.getConfig('crowi', 'security:registrationMode') !== RegistrationMode.CLOSED;
+  && configManager.getConfig('security:registrationMode') !== RegistrationMode.CLOSED;
 
-  props.adminPreferredIndentSize = configManager.getConfig('markdown', 'markdown:adminPreferredIndentSize');
-  props.isIndentSizeForced = configManager.getConfig('markdown', 'markdown:isIndentSizeForced');
+  props.adminPreferredIndentSize = configManager.getConfig('markdown:adminPreferredIndentSize');
+  props.isIndentSizeForced = configManager.getConfig('markdown:isIndentSizeForced');
 
-  props.isEnabledAttachTitleHeader = configManager.getConfig('crowi', 'customize:isEnabledAttachTitleHeader');
+  props.isEnabledAttachTitleHeader = configManager.getConfig('customize:isEnabledAttachTitleHeader');
 
   props.sidebarConfig = {
-    isSidebarCollapsedMode: configManager.getConfig('crowi', 'customize:isSidebarCollapsedMode'),
-    isSidebarClosedAtDockMode: configManager.getConfig('crowi', 'customize:isSidebarClosedAtDockMode'),
+    isSidebarCollapsedMode: configManager.getConfig('customize:isSidebarCollapsedMode'),
+    isSidebarClosedAtDockMode: configManager.getConfig('customize:isSidebarClosedAtDockMode'),
   };
 
   props.rendererConfig = {
-    isEnabledLinebreaks: configManager.getConfig('markdown', 'markdown:isEnabledLinebreaks'),
-    isEnabledLinebreaksInComments: configManager.getConfig('markdown', 'markdown:isEnabledLinebreaksInComments'),
-    isEnabledMarp: configManager.getConfig('crowi', 'customize:isEnabledMarp'),
-    adminPreferredIndentSize: configManager.getConfig('markdown', 'markdown:adminPreferredIndentSize'),
-    isIndentSizeForced: configManager.getConfig('markdown', 'markdown:isIndentSizeForced'),
+    isEnabledLinebreaks: configManager.getConfig('markdown:isEnabledLinebreaks'),
+    isEnabledLinebreaksInComments: configManager.getConfig('markdown:isEnabledLinebreaksInComments'),
+    isEnabledMarp: configManager.getConfig('customize:isEnabledMarp'),
+    adminPreferredIndentSize: configManager.getConfig('markdown:adminPreferredIndentSize'),
+    isIndentSizeForced: configManager.getConfig('markdown:isIndentSizeForced'),
 
-    drawioUri: configManager.getConfig('crowi', 'app:drawioUri'),
-    plantumlUri: configManager.getConfig('crowi', 'app:plantumlUri'),
+    drawioUri: configManager.getConfig('app:drawioUri'),
+    plantumlUri: configManager.getConfig('app:plantumlUri'),
 
     // XSS Options
-    isEnabledXssPrevention: configManager.getConfig('markdown', 'markdown:rehypeSanitize:isEnabledPrevention'),
-    sanitizeType: configManager.getConfig('markdown', 'markdown:rehypeSanitize:option'),
-    customTagWhitelist: configManager.getConfig('markdown', 'markdown:rehypeSanitize:tagNames'),
-    customAttrWhitelist: configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes') != null
-      ? JSON.parse(configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes'))
+    isEnabledXssPrevention: configManager.getConfig('markdown:rehypeSanitize:isEnabledPrevention'),
+    sanitizeType: configManager.getConfig('markdown:rehypeSanitize:option'),
+    customTagWhitelist: configManager.getConfig('markdown:rehypeSanitize:tagNames'),
+    customAttrWhitelist: configManager.getConfig('markdown:rehypeSanitize:attributes') != null
+      ? JSON.parse(configManager.getConfig('markdown:rehypeSanitize:attributes'))
       : undefined,
-    highlightJsStyleBorder: configManager.getConfig('crowi', 'customize:highlightJsStyleBorder'),
+    highlightJsStyleBorder: configManager.getConfig('customize:highlightJsStyleBorder'),
   };
 
-  props.ssrMaxRevisionBodyLength = configManager.getConfig('crowi', 'app:ssrMaxRevisionBodyLength');
+  props.ssrMaxRevisionBodyLength = configManager.getConfig('app:ssrMaxRevisionBodyLength');
 }
 
 /**

+ 17 - 17
apps/app/src/pages/_private-legacy-pages.page.tsx

@@ -94,32 +94,32 @@ async function injectServerConfigurations(context: GetServerSidePropsContext, pr
 
   props.isSearchServiceConfigured = searchService.isConfigured;
   props.isSearchServiceReachable = searchService.isReachable;
-  props.isSearchScopeChildrenAsDefault = configManager.getConfig('crowi', 'customize:isSearchScopeChildrenAsDefault');
-  props.isEnabledMarp = configManager.getConfig('crowi', 'customize:isEnabledMarp');
+  props.isSearchScopeChildrenAsDefault = configManager.getConfig('customize:isSearchScopeChildrenAsDefault');
+  props.isEnabledMarp = configManager.getConfig('customize:isEnabledMarp');
 
   props.sidebarConfig = {
-    isSidebarCollapsedMode: configManager.getConfig('crowi', 'customize:isSidebarCollapsedMode'),
-    isSidebarClosedAtDockMode: configManager.getConfig('crowi', 'customize:isSidebarClosedAtDockMode'),
+    isSidebarCollapsedMode: configManager.getConfig('customize:isSidebarCollapsedMode'),
+    isSidebarClosedAtDockMode: configManager.getConfig('customize:isSidebarClosedAtDockMode'),
   };
 
   props.rendererConfig = {
-    isEnabledLinebreaks: configManager.getConfig('markdown', 'markdown:isEnabledLinebreaks'),
-    isEnabledLinebreaksInComments: configManager.getConfig('markdown', 'markdown:isEnabledLinebreaksInComments'),
-    isEnabledMarp: configManager.getConfig('crowi', 'customize:isEnabledMarp'),
-    adminPreferredIndentSize: configManager.getConfig('markdown', 'markdown:adminPreferredIndentSize'),
-    isIndentSizeForced: configManager.getConfig('markdown', 'markdown:isIndentSizeForced'),
+    isEnabledLinebreaks: configManager.getConfig('markdown:isEnabledLinebreaks'),
+    isEnabledLinebreaksInComments: configManager.getConfig('markdown:isEnabledLinebreaksInComments'),
+    isEnabledMarp: configManager.getConfig('customize:isEnabledMarp'),
+    adminPreferredIndentSize: configManager.getConfig('markdown:adminPreferredIndentSize'),
+    isIndentSizeForced: configManager.getConfig('markdown:isIndentSizeForced'),
 
-    drawioUri: configManager.getConfig('crowi', 'app:drawioUri'),
-    plantumlUri: configManager.getConfig('crowi', 'app:plantumlUri'),
+    drawioUri: configManager.getConfig('app:drawioUri'),
+    plantumlUri: configManager.getConfig('app:plantumlUri'),
 
     // XSS Options
-    isEnabledXssPrevention: configManager.getConfig('markdown', 'markdown:rehypeSanitize:isEnabledPrevention'),
-    sanitizeType: configManager.getConfig('markdown', 'markdown:rehypeSanitize:option'),
-    customTagWhitelist: crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:tagNames'),
-    customAttrWhitelist: configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes') != null
-      ? JSON.parse(configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes'))
+    isEnabledXssPrevention: configManager.getConfig('markdown:rehypeSanitize:isEnabledPrevention'),
+    sanitizeType: configManager.getConfig('markdown:rehypeSanitize:option'),
+    customTagWhitelist: crowi.configManager.getConfig('markdown:rehypeSanitize:tagNames'),
+    customAttrWhitelist: configManager.getConfig('markdown:rehypeSanitize:attributes') != null
+      ? JSON.parse(configManager.getConfig('markdown:rehypeSanitize:attributes'))
       : undefined,
-    highlightJsStyleBorder: crowi.configManager.getConfig('crowi', 'customize:highlightJsStyleBorder'),
+    highlightJsStyleBorder: crowi.configManager.getConfig('customize:highlightJsStyleBorder'),
   };
 }
 

+ 18 - 18
apps/app/src/pages/_search.page.tsx

@@ -121,35 +121,35 @@ function injectServerConfigurations(context: GetServerSidePropsContext, props: P
 
   props.isSearchServiceConfigured = searchService.isConfigured;
   props.isSearchServiceReachable = searchService.isReachable;
-  props.isSearchScopeChildrenAsDefault = configManager.getConfig('crowi', 'customize:isSearchScopeChildrenAsDefault');
-  props.isContainerFluid = configManager.getConfig('crowi', 'customize:isContainerFluid');
+  props.isSearchScopeChildrenAsDefault = configManager.getConfig('customize:isSearchScopeChildrenAsDefault');
+  props.isContainerFluid = configManager.getConfig('customize:isContainerFluid');
 
   props.sidebarConfig = {
-    isSidebarCollapsedMode: configManager.getConfig('crowi', 'customize:isSidebarCollapsedMode'),
-    isSidebarClosedAtDockMode: configManager.getConfig('crowi', 'customize:isSidebarClosedAtDockMode'),
+    isSidebarCollapsedMode: configManager.getConfig('customize:isSidebarCollapsedMode'),
+    isSidebarClosedAtDockMode: configManager.getConfig('customize:isSidebarClosedAtDockMode'),
   };
 
   props.rendererConfig = {
-    isEnabledLinebreaks: configManager.getConfig('markdown', 'markdown:isEnabledLinebreaks'),
-    isEnabledLinebreaksInComments: configManager.getConfig('markdown', 'markdown:isEnabledLinebreaksInComments'),
-    isEnabledMarp: configManager.getConfig('crowi', 'customize:isEnabledMarp'),
-    adminPreferredIndentSize: configManager.getConfig('markdown', 'markdown:adminPreferredIndentSize'),
-    isIndentSizeForced: configManager.getConfig('markdown', 'markdown:isIndentSizeForced'),
+    isEnabledLinebreaks: configManager.getConfig('markdown:isEnabledLinebreaks'),
+    isEnabledLinebreaksInComments: configManager.getConfig('markdown:isEnabledLinebreaksInComments'),
+    isEnabledMarp: configManager.getConfig('customize:isEnabledMarp'),
+    adminPreferredIndentSize: configManager.getConfig('markdown:adminPreferredIndentSize'),
+    isIndentSizeForced: configManager.getConfig('markdown:isIndentSizeForced'),
 
-    drawioUri: configManager.getConfig('crowi', 'app:drawioUri'),
-    plantumlUri: configManager.getConfig('crowi', 'app:plantumlUri'),
+    drawioUri: configManager.getConfig('app:drawioUri'),
+    plantumlUri: configManager.getConfig('app:plantumlUri'),
 
     // XSS Options
-    isEnabledXssPrevention: configManager.getConfig('markdown', 'markdown:rehypeSanitize:isEnabledPrevention'),
-    sanitizeType: configManager.getConfig('markdown', 'markdown:rehypeSanitize:option'),
-    customTagWhitelist: crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:tagNames'),
-    customAttrWhitelist: configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes') != null
-      ? JSON.parse(configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes'))
+    isEnabledXssPrevention: configManager.getConfig('markdown:rehypeSanitize:isEnabledPrevention'),
+    sanitizeType: configManager.getConfig('markdown:rehypeSanitize:option'),
+    customTagWhitelist: crowi.configManager.getConfig('markdown:rehypeSanitize:tagNames'),
+    customAttrWhitelist: configManager.getConfig('markdown:rehypeSanitize:attributes') != null
+      ? JSON.parse(configManager.getConfig('markdown:rehypeSanitize:attributes'))
       : undefined,
-    highlightJsStyleBorder: crowi.configManager.getConfig('crowi', 'customize:highlightJsStyleBorder'),
+    highlightJsStyleBorder: crowi.configManager.getConfig('customize:highlightJsStyleBorder'),
   };
 
-  props.showPageLimitationL = configManager.getConfig('crowi', 'customize:showPageLimitationL');
+  props.showPageLimitationL = configManager.getConfig('customize:showPageLimitationL');
 }
 
 /**

+ 1 - 1
apps/app/src/pages/admin/ai-integration.page.tsx

@@ -50,7 +50,7 @@ const injectServerConfigurations = async(context: GetServerSidePropsContext, pro
   const { crowi } = req;
   const { configManager } = crowi;
 
-  props.aiEnabled = configManager.getConfig('crowi', 'app:aiEnabled');
+  props.aiEnabled = configManager.getConfig('app:aiEnabled');
 };
 
 export const getServerSideProps: GetServerSideProps = async(context: GetServerSidePropsContext) => {

+ 2 - 2
apps/app/src/pages/admin/audit-log.page.tsx

@@ -57,8 +57,8 @@ const injectServerConfigurations = async(context: GetServerSidePropsContext, pro
   const { crowi } = req;
   const { activityService } = crowi;
 
-  props.auditLogEnabled = crowi.configManager.getConfig('crowi', 'app:auditLogEnabled');
-  props.activityExpirationSeconds = crowi.configManager.getConfig('crowi', 'app:activityExpirationSeconds');
+  props.auditLogEnabled = crowi.configManager.getConfig('app:auditLogEnabled');
+  props.activityExpirationSeconds = crowi.configManager.getConfig('app:activityExpirationSeconds');
   props.auditLogAvailableActions = activityService.getAvailableActions(false);
 };
 

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

@@ -67,7 +67,7 @@ const injectServerConfigurations = async(context: GetServerSidePropsContext, pro
   const req: CrowiRequest = context.req as CrowiRequest;
   const { crowi } = req;
 
-  props.customizeTitle = crowi.configManager.getConfig('crowi', 'customize:title');
+  props.customizeTitle = crowi.configManager.getConfig('customize:title');
   props.isCustomizedLogoUploaded = await crowi.attachmentService.isBrandLogoExist();
 };
 

+ 1 - 1
apps/app/src/pages/admin/data-transfer.page.tsx

@@ -60,7 +60,7 @@ const injectServerConfigurations = async(context: GetServerSidePropsContext, pro
   const req: CrowiRequest = context.req as CrowiRequest;
   const { crowi } = req;
 
-  props.growiCloudUri = await crowi.configManager.getConfig('crowi', 'app:growiCloudUri');
+  props.growiCloudUri = await crowi.configManager.getConfig('app:growiCloudUri');
 };
 
 export const getServerSideProps: GetServerSideProps = async(context: GetServerSidePropsContext) => {

+ 2 - 2
apps/app/src/pages/admin/index.page.tsx

@@ -71,8 +71,8 @@ const injectServerConfigurations = async(context: GetServerSidePropsContext, pro
   const req: CrowiRequest = context.req as CrowiRequest;
   const { crowi } = req;
 
-  props.growiCloudUri = crowi.configManager.getConfig('crowi', 'app:growiCloudUri');
-  props.growiAppIdForGrowiCloud = crowi.configManager.getConfig('crowi', 'app:growiAppIdForCloud');
+  props.growiCloudUri = crowi.configManager.getConfig('app:growiCloudUri');
+  props.growiAppIdForGrowiCloud = crowi.configManager.getConfig('app:growiAppIdForCloud');
 };
 
 

+ 1 - 1
apps/app/src/pages/installer.page.tsx

@@ -79,7 +79,7 @@ async function injectServerConfigurations(context: GetServerSidePropsContext, pr
   const { crowi } = req;
   const { configManager } = crowi;
 
-  props.minPasswordLength = configManager.getConfig('crowi', 'app:minPasswordLength');
+  props.minPasswordLength = configManager.getConfig('app:minPasswordLength');
 }
 
 export const getServerSideProps: GetServerSideProps = async(context: GetServerSidePropsContext) => {

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

@@ -95,11 +95,11 @@ function injectEnabledStrategies(context: GetServerSidePropsContext, props: Prop
   } = crowi;
 
   props.enabledExternalAuthType = [
-    configManager.getConfig('crowi', 'security:passport-google:isEnabled') === true ? IExternalAuthProviderType.google : undefined,
-    configManager.getConfig('crowi', 'security:passport-github:isEnabled') === true ? IExternalAuthProviderType.github : undefined,
-    // configManager.getConfig('crowi', 'security:passport-facebook:isEnabled') ?? IExternalAuthProviderType.facebook : undefined,
-    configManager.getConfig('crowi', 'security:passport-saml:isEnabled') === true ? IExternalAuthProviderType.saml : undefined,
-    configManager.getConfig('crowi', 'security:passport-oidc:isEnabled') === true ? IExternalAuthProviderType.oidc : undefined,
+    configManager.getConfig('security:passport-google:isEnabled') === true ? IExternalAuthProviderType.google : undefined,
+    configManager.getConfig('security:passport-github:isEnabled') === true ? IExternalAuthProviderType.github : undefined,
+    // configManager.getConfig('security:passport-facebook:isEnabled') ?? IExternalAuthProviderType.facebook : undefined,
+    configManager.getConfig('security:passport-saml:isEnabled') === true ? IExternalAuthProviderType.saml : undefined,
+    configManager.getConfig('security:passport-oidc:isEnabled') === true ? IExternalAuthProviderType.oidc : undefined,
 
   ]
     .filter((authType): authType is Exclude<typeof authType, undefined> => authType != null);
@@ -114,15 +114,15 @@ async function injectServerConfigurations(context: GetServerSidePropsContext, pr
     passportService,
   } = crowi;
 
-  props.isPasswordResetEnabled = configManager.getConfig('crowi', 'security:passport-local:isPasswordResetEnabled');
+  props.isPasswordResetEnabled = configManager.getConfig('security:passport-local:isPasswordResetEnabled');
   props.isMailerSetup = mailService.isMailerSetup;
   props.isLocalStrategySetup = passportService.isLocalStrategySetup;
   props.isLdapStrategySetup = passportService.isLdapStrategySetup;
-  props.isLdapSetupFailed = configManager.getConfig('crowi', 'security:passport-ldap:isEnabled') && !props.isLdapStrategySetup;
-  props.registrationWhitelist = configManager.getConfig('crowi', 'security:registrationWhitelist');
-  props.isEmailAuthenticationEnabled = configManager.getConfig('crowi', 'security:passport-local:isEmailAuthenticationEnabled');
-  props.registrationMode = configManager.getConfig('crowi', 'security:registrationMode');
-  props.minPasswordLength = configManager.getConfig('crowi', 'app:minPasswordLength');
+  props.isLdapSetupFailed = configManager.getConfig('security:passport-ldap:isEnabled') && !props.isLdapStrategySetup;
+  props.registrationWhitelist = configManager.getConfig('security:registrationWhitelist');
+  props.isEmailAuthenticationEnabled = configManager.getConfig('security:passport-local:isEmailAuthenticationEnabled');
+  props.registrationMode = configManager.getConfig('security:registrationMode');
+  props.minPasswordLength = configManager.getConfig('app:minPasswordLength');
 }
 
 export const getServerSideProps: GetServerSideProps = async(context: GetServerSidePropsContext) => {

+ 18 - 18
apps/app/src/pages/me/[[...path]].page.tsx

@@ -173,35 +173,35 @@ async function injectServerConfigurations(context: GetServerSidePropsContext, pr
 
   props.isSearchServiceConfigured = searchService.isConfigured;
   props.isSearchServiceReachable = searchService.isReachable;
-  props.isSearchScopeChildrenAsDefault = configManager.getConfig('crowi', 'customize:isSearchScopeChildrenAsDefault');
+  props.isSearchScopeChildrenAsDefault = configManager.getConfig('customize:isSearchScopeChildrenAsDefault');
 
-  props.registrationWhitelist = configManager.getConfig('crowi', 'security:registrationWhitelist');
+  props.registrationWhitelist = configManager.getConfig('security:registrationWhitelist');
 
-  props.showPageLimitationXL = crowi.configManager.getConfig('crowi', 'customize:showPageLimitationXL');
+  props.showPageLimitationXL = crowi.configManager.getConfig('customize:showPageLimitationXL');
 
   props.sidebarConfig = {
-    isSidebarCollapsedMode: configManager.getConfig('crowi', 'customize:isSidebarCollapsedMode'),
-    isSidebarClosedAtDockMode: configManager.getConfig('crowi', 'customize:isSidebarClosedAtDockMode'),
+    isSidebarCollapsedMode: configManager.getConfig('customize:isSidebarCollapsedMode'),
+    isSidebarClosedAtDockMode: configManager.getConfig('customize:isSidebarClosedAtDockMode'),
   };
 
   props.rendererConfig = {
-    isEnabledLinebreaks: configManager.getConfig('markdown', 'markdown:isEnabledLinebreaks'),
-    isEnabledLinebreaksInComments: configManager.getConfig('markdown', 'markdown:isEnabledLinebreaksInComments'),
-    isEnabledMarp: configManager.getConfig('crowi', 'customize:isEnabledMarp'),
-    adminPreferredIndentSize: configManager.getConfig('markdown', 'markdown:adminPreferredIndentSize'),
-    isIndentSizeForced: configManager.getConfig('markdown', 'markdown:isIndentSizeForced'),
+    isEnabledLinebreaks: configManager.getConfig('markdown:isEnabledLinebreaks'),
+    isEnabledLinebreaksInComments: configManager.getConfig('markdown:isEnabledLinebreaksInComments'),
+    isEnabledMarp: configManager.getConfig('customize:isEnabledMarp'),
+    adminPreferredIndentSize: configManager.getConfig('markdown:adminPreferredIndentSize'),
+    isIndentSizeForced: configManager.getConfig('markdown:isIndentSizeForced'),
 
-    drawioUri: configManager.getConfig('crowi', 'app:drawioUri'),
-    plantumlUri: configManager.getConfig('crowi', 'app:plantumlUri'),
+    drawioUri: configManager.getConfig('app:drawioUri'),
+    plantumlUri: configManager.getConfig('app:plantumlUri'),
 
     // XSS Options
-    isEnabledXssPrevention: configManager.getConfig('markdown', 'markdown:rehypeSanitize:isEnabledPrevention'),
-    sanitizeType: configManager.getConfig('markdown', 'markdown:rehypeSanitize:option'),
-    customTagWhitelist: crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:tagNames'),
-    customAttrWhitelist: configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes') != null
-      ? JSON.parse(configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes'))
+    isEnabledXssPrevention: configManager.getConfig('markdown:rehypeSanitize:isEnabledPrevention'),
+    sanitizeType: configManager.getConfig('markdown:rehypeSanitize:option'),
+    customTagWhitelist: crowi.configManager.getConfig('markdown:rehypeSanitize:tagNames'),
+    customAttrWhitelist: configManager.getConfig('markdown:rehypeSanitize:attributes') != null
+      ? JSON.parse(configManager.getConfig('markdown:rehypeSanitize:attributes'))
       : undefined,
-    highlightJsStyleBorder: crowi.configManager.getConfig('crowi', 'customize:highlightJsStyleBorder'),
+    highlightJsStyleBorder: crowi.configManager.getConfig('customize:highlightJsStyleBorder'),
   };
 }
 

+ 19 - 19
apps/app/src/pages/share/[[...path]].page.tsx

@@ -159,39 +159,39 @@ function injectServerConfigurations(context: GetServerSidePropsContext, props: P
   const { crowi } = req;
   const { configManager, searchService } = crowi;
 
-  props.disableLinkSharing = configManager.getConfig('crowi', 'security:disableLinkSharing');
+  props.disableLinkSharing = configManager.getConfig('security:disableLinkSharing');
 
   props.isSearchServiceConfigured = searchService.isConfigured;
   props.isSearchServiceReachable = searchService.isReachable;
-  props.isSearchScopeChildrenAsDefault = configManager.getConfig('crowi', 'customize:isSearchScopeChildrenAsDefault');
+  props.isSearchScopeChildrenAsDefault = configManager.getConfig('customize:isSearchScopeChildrenAsDefault');
 
-  props.drawioUri = configManager.getConfig('crowi', 'app:drawioUri');
+  props.drawioUri = configManager.getConfig('app:drawioUri');
 
   props.isLocalAccountRegistrationEnabled = crowi.passportService.isLocalStrategySetup
-    && configManager.getConfig('crowi', 'security:registrationMode') !== RegistrationMode.CLOSED;
+    && configManager.getConfig('security:registrationMode') !== RegistrationMode.CLOSED;
 
   props.rendererConfig = {
     isSharedPage: true,
-    isEnabledLinebreaks: configManager.getConfig('markdown', 'markdown:isEnabledLinebreaks'),
-    isEnabledLinebreaksInComments: configManager.getConfig('markdown', 'markdown:isEnabledLinebreaksInComments'),
-    isEnabledMarp: configManager.getConfig('crowi', 'customize:isEnabledMarp'),
-    adminPreferredIndentSize: configManager.getConfig('markdown', 'markdown:adminPreferredIndentSize'),
-    isIndentSizeForced: configManager.getConfig('markdown', 'markdown:isIndentSizeForced'),
+    isEnabledLinebreaks: configManager.getConfig('markdown:isEnabledLinebreaks'),
+    isEnabledLinebreaksInComments: configManager.getConfig('markdown:isEnabledLinebreaksInComments'),
+    isEnabledMarp: configManager.getConfig('customize:isEnabledMarp'),
+    adminPreferredIndentSize: configManager.getConfig('markdown:adminPreferredIndentSize'),
+    isIndentSizeForced: configManager.getConfig('markdown:isIndentSizeForced'),
 
-    drawioUri: configManager.getConfig('crowi', 'app:drawioUri'),
-    plantumlUri: configManager.getConfig('crowi', 'app:plantumlUri'),
+    drawioUri: configManager.getConfig('app:drawioUri'),
+    plantumlUri: configManager.getConfig('app:plantumlUri'),
 
     // XSS Options
-    isEnabledXssPrevention: configManager.getConfig('markdown', 'markdown:rehypeSanitize:isEnabledPrevention'),
-    sanitizeType: configManager.getConfig('markdown', 'markdown:rehypeSanitize:option'),
-    customTagWhitelist: crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:tagNames'),
-    customAttrWhitelist: configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes') != null
-      ? JSON.parse(configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes'))
+    isEnabledXssPrevention: configManager.getConfig('markdown:rehypeSanitize:isEnabledPrevention'),
+    sanitizeType: configManager.getConfig('markdown:rehypeSanitize:option'),
+    customTagWhitelist: crowi.configManager.getConfig('markdown:rehypeSanitize:tagNames'),
+    customAttrWhitelist: configManager.getConfig('markdown:rehypeSanitize:attributes') != null
+      ? JSON.parse(configManager.getConfig('markdown:rehypeSanitize:attributes'))
       : undefined,
-    highlightJsStyleBorder: crowi.configManager.getConfig('crowi', 'customize:highlightJsStyleBorder'),
+    highlightJsStyleBorder: crowi.configManager.getConfig('customize:highlightJsStyleBorder'),
   };
 
-  props.ssrMaxRevisionBodyLength = configManager.getConfig('crowi', 'app:ssrMaxRevisionBodyLength');
+  props.ssrMaxRevisionBodyLength = configManager.getConfig('app:ssrMaxRevisionBodyLength');
 }
 
 async function injectNextI18NextConfigurations(context: GetServerSidePropsContext, props: Props, namespacesRequired?: string[] | undefined): Promise<void> {
@@ -237,7 +237,7 @@ export const getServerSideProps: GetServerSideProps = async(context: GetServerSi
       const Page = crowi.model('Page');
       const relatedPage = await Page.findOne({ _id: getIdForRef(shareLink.relatedPage) });
       // determine whether skip SSR
-      const ssrMaxRevisionBodyLength = crowi.configManager.getConfig('crowi', 'app:ssrMaxRevisionBodyLength');
+      const ssrMaxRevisionBodyLength = crowi.configManager.getConfig('app:ssrMaxRevisionBodyLength');
       props.skipSSR = await skipSSR(relatedPage, ssrMaxRevisionBodyLength);
       // populate
       props.shareLinkRelatedPage = await relatedPage.populateDataToShowRevision(props.skipSSR); // shouldExcludeBody = skipSSR

+ 3 - 3
apps/app/src/pages/tags.page.tsx

@@ -152,11 +152,11 @@ function injectServerConfigurations(context: GetServerSidePropsContext, props: P
 
   props.isSearchServiceConfigured = searchService.isConfigured;
   props.isSearchServiceReachable = searchService.isReachable;
-  props.isSearchScopeChildrenAsDefault = configManager.getConfig('crowi', 'customize:isSearchScopeChildrenAsDefault');
+  props.isSearchScopeChildrenAsDefault = configManager.getConfig('customize:isSearchScopeChildrenAsDefault');
 
   props.sidebarConfig = {
-    isSidebarCollapsedMode: configManager.getConfig('crowi', 'customize:isSidebarCollapsedMode'),
-    isSidebarClosedAtDockMode: configManager.getConfig('crowi', 'customize:isSidebarClosedAtDockMode'),
+    isSidebarCollapsedMode: configManager.getConfig('customize:isSidebarCollapsedMode'),
+    isSidebarClosedAtDockMode: configManager.getConfig('customize:isSidebarClosedAtDockMode'),
   };
 
 }

+ 4 - 4
apps/app/src/pages/trash.page.tsx

@@ -117,12 +117,12 @@ function injectServerConfigurations(context: GetServerSidePropsContext, props: P
 
   props.isSearchServiceConfigured = searchService.isConfigured;
   props.isSearchServiceReachable = searchService.isReachable;
-  props.isSearchScopeChildrenAsDefault = configManager.getConfig('crowi', 'customize:isSearchScopeChildrenAsDefault');
-  props.showPageLimitationXL = crowi.configManager.getConfig('crowi', 'customize:showPageLimitationXL');
+  props.isSearchScopeChildrenAsDefault = configManager.getConfig('customize:isSearchScopeChildrenAsDefault');
+  props.showPageLimitationXL = crowi.configManager.getConfig('customize:showPageLimitationXL');
 
   props.sidebarConfig = {
-    isSidebarCollapsedMode: configManager.getConfig('crowi', 'customize:isSidebarCollapsedMode'),
-    isSidebarClosedAtDockMode: configManager.getConfig('crowi', 'customize:isSidebarClosedAtDockMode'),
+    isSidebarCollapsedMode: configManager.getConfig('customize:isSidebarCollapsedMode'),
+    isSidebarClosedAtDockMode: configManager.getConfig('customize:isSidebarClosedAtDockMode'),
   };
 
 }

+ 2 - 2
apps/app/src/pages/user-activation.page.tsx

@@ -81,8 +81,8 @@ export const getServerSideProps: GetServerSideProps = async(context: GetServerSi
   if (typeof context.query.errorCode === 'string') {
     props.errorCode = context.query.errorCode as UserActivationErrorCode;
   }
-  props.registrationMode = req.crowi.configManager.getConfig('crowi', 'security:registrationMode');
-  props.isEmailAuthenticationEnabled = req.crowi.configManager.getConfig('crowi', 'security:passport-local:isEmailAuthenticationEnabled');
+  props.registrationMode = req.crowi.configManager.getConfig('security:registrationMode');
+  props.isEmailAuthenticationEnabled = req.crowi.configManager.getConfig('security:passport-local:isEmailAuthenticationEnabled');
 
   await injectNextI18NextConfigurations(context, props, ['translation']);
 

+ 5 - 5
apps/app/src/pages/utils/commons.ts

@@ -74,7 +74,7 @@ export const getServerSideCommonProps: GetServerSideProps<CommonProps> = async(c
   }
 
   const isCustomizedLogoUploaded = await attachmentService.isBrandLogoExist();
-  const isDefaultLogo = crowi.configManager.getConfig('crowi', 'customize:isDefaultLogo') || !isCustomizedLogoUploaded;
+  const isDefaultLogo = crowi.configManager.getConfig('customize:isDefaultLogo') || !isCustomizedLogoUploaded;
   const forcedColorScheme = crowi.customizeService.forcedColorScheme;
 
   // retrieve UserUISett ings
@@ -87,18 +87,18 @@ export const getServerSideCommonProps: GetServerSideProps<CommonProps> = async(c
     namespacesRequired: ['translation'],
     currentPathname,
     appTitle: appService.getAppTitle(),
-    siteUrl: configManager.getConfig('crowi', 'app:siteUrl'), // DON'T USE appService.getSiteUrl()
+    siteUrl: configManager.getConfig('app:siteUrl'), // DON'T USE appService.getSiteUrl()
     confidential: appService.getAppConfidential() || '',
     customTitleTemplate: customizeService.customTitleTemplate,
     csrfToken: req.csrfToken(),
-    isContainerFluid: configManager.getConfig('crowi', 'customize:isContainerFluid') ?? false,
+    isContainerFluid: configManager.getConfig('customize:isContainerFluid') ?? false,
     growiVersion: crowi.version,
     isMaintenanceMode,
     redirectDestination,
     currentUser,
     isDefaultLogo,
     forcedColorScheme,
-    growiCloudUri: configManager.getConfig('crowi', 'app:growiCloudUri'),
+    growiCloudUri: configManager.getConfig('app:growiCloudUri'),
     userUISettings: userUISettings?.toObject?.() ?? userUISettings,
   };
 
@@ -122,7 +122,7 @@ export const getLangAtServerSide = (req: CrowiRequest): Lang => {
   const { configManager } = req.crowi;
 
   return user == null ? detectLocaleFromBrowserAcceptLanguage(headers)
-    : (user.lang ?? configManager.getConfig('crowi', 'app:globalLang') as Lang ?? Lang.en_US) ?? Lang.en_US;
+    : (user.lang ?? configManager.getConfig('app:globalLang') ?? Lang.en_US) ?? Lang.en_US;
 };
 
 // use this function to get locale for html lang attribute

+ 3 - 3
apps/app/src/server/crowi/express-init.js

@@ -39,9 +39,9 @@ module.exports = function(crowi, app) {
 
   const { configManager } = crowi;
 
-  const trustProxyBool = configManager.getConfig('crowi', 'security:trustProxyBool');
-  const trustProxyCsv = configManager.getConfig('crowi', 'security:trustProxyCsv');
-  const trustProxyHops = configManager.getConfig('crowi', 'security:trustProxyHops');
+  const trustProxyBool = configManager.getConfig('security:trustProxyBool');
+  const trustProxyCsv = configManager.getConfig('security:trustProxyCsv');
+  const trustProxyHops = configManager.getConfig('security:trustProxyHops');
 
   const trustProxy = trustProxyBool ?? trustProxyCsv ?? trustProxyHops;
 

+ 10 - 10
apps/app/src/server/crowi/index.js

@@ -273,7 +273,7 @@ Crowi.prototype.setupDatabase = function() {
 
 Crowi.prototype.setupSessionConfig = async function() {
   const session = require('express-session');
-  const sessionMaxAge = this.configManager.getConfig('crowi', 'security:sessionMaxAge') || 2592000000; // default: 30days
+  const sessionMaxAge = this.configManager.getConfig('security:sessionMaxAge') || 2592000000; // default: 30days
   const redisUrl = this.env.REDISTOGO_URL || this.env.REDIS_URI || this.env.REDIS_URL || null;
   const uid = require('uid-safe').sync;
 
@@ -413,8 +413,8 @@ Crowi.prototype.setupMailer = async function() {
 };
 
 Crowi.prototype.autoInstall = async function() {
-  const isInstalled = this.configManager.getConfig('crowi', 'app:installed');
-  const username = this.configManager.getConfig('crowi', 'autoInstall:adminUsername');
+  const isInstalled = this.configManager.getConfig('app:installed');
+  const username = this.configManager.getConfig('autoInstall:adminUsername');
 
   if (isInstalled || username == null) {
     return;
@@ -424,14 +424,14 @@ Crowi.prototype.autoInstall = async function() {
 
   const firstAdminUserToSave = {
     username,
-    name: this.configManager.getConfig('crowi', 'autoInstall:adminName'),
-    email: this.configManager.getConfig('crowi', 'autoInstall:adminEmail'),
-    password: this.configManager.getConfig('crowi', 'autoInstall:adminPassword'),
+    name: this.configManager.getConfig('autoInstall:adminName'),
+    email: this.configManager.getConfig('autoInstall:adminEmail'),
+    password: this.configManager.getConfig('autoInstall:adminPassword'),
     admin: true,
   };
-  const globalLang = this.configManager.getConfig('crowi', 'autoInstall:globalLang');
-  const allowGuestMode = this.configManager.getConfig('crowi', 'autoInstall:allowGuestMode');
-  const serverDate = this.configManager.getConfig('crowi', 'autoInstall:serverDate');
+  const globalLang = this.configManager.getConfig('autoInstall:globalLang');
+  const allowGuestMode = this.configManager.getConfig('autoInstall:allowGuestMode');
+  const serverDate = this.configManager.getConfig('autoInstall:serverDate');
 
   const installerService = new InstallerService(this);
 
@@ -629,7 +629,7 @@ Crowi.prototype.setUpApp = async function() {
     this.appService = new AppService(this);
 
     // add as a message handler
-    const isInstalled = this.configManager.getConfig('crowi', 'app:installed');
+    const isInstalled = this.configManager.getConfig('app:installed');
     if (this.s2sMessagingService != null && !isInstalled) {
       this.s2sMessagingService.addMessageHandler(this.appService);
     }

+ 1 - 1
apps/app/src/server/middlewares/certify-shared-page-attachment/validate-referer/retrieve-site-url.ts

@@ -6,7 +6,7 @@ const logger = loggerFactory('growi:middlewares:certify-shared-page-attachment:v
 
 
 export const retrieveSiteUrl = (): URL | null => {
-  const siteUrlString = configManager.getConfig('crowi', 'app:siteUrl');
+  const siteUrlString = configManager.getConfig('app:siteUrl');
   if (siteUrlString == null) {
     logger.warn("Verification referer does not work because 'Site URL' is NOT set. All of attachments in share link page is invisible.");
     return null;

+ 1 - 1
apps/app/src/server/middlewares/exclude-read-only-user.ts

@@ -30,7 +30,7 @@ export const excludeReadOnlyUser = (req: Request, res: Response & { apiv3Err },
 export const excludeReadOnlyUserIfCommentNotAllowed = (req: Request, res: Response & { apiv3Err }, next: () => NextFunction): NextFunction => {
   const user = req.user;
 
-  const isRomUserAllowedToComment = configManager.getConfig('crowi', 'security:isRomUserAllowedToComment');
+  const isRomUserAllowedToComment = configManager.getConfig('security:isRomUserAllowedToComment');
 
   if (user == null) {
     logger.warn('req.user is null');

+ 2 - 2
apps/app/src/server/models/obsolete-page.js

@@ -513,8 +513,8 @@ export const getPageSchema = (crowi) => {
     validateCrowi();
 
     // determine User condition
-    const hidePagesRestrictedByOwner = crowi.configManager.getConfig('crowi', 'security:list-policy:hideRestrictedByOwner');
-    const hidePagesRestrictedByGroup = crowi.configManager.getConfig('crowi', 'security:list-policy:hideRestrictedByGroup');
+    const hidePagesRestrictedByOwner = crowi.configManager.getConfig('security:list-policy:hideRestrictedByOwner');
+    const hidePagesRestrictedByGroup = crowi.configManager.getConfig('security:list-policy:hideRestrictedByGroup');
 
     // determine UserGroup condition
     const userGroups = user != null ? [

+ 2 - 2
apps/app/src/server/models/slack-app-integration.js

@@ -38,8 +38,8 @@ class SlackAppIntegration {
     let generateTokens;
 
     // get salt strings
-    const saltForGtoP = this.crowi.configManager.getConfig('crowi', 'slackbot:withProxy:saltForGtoP');
-    const saltForPtoG = this.crowi.configManager.getConfig('crowi', 'slackbot:withProxy:saltForPtoG');
+    const saltForGtoP = this.crowi.configManager.getConfig('slackbot:withProxy:saltForGtoP');
+    const saltForPtoG = this.crowi.configManager.getConfig('slackbot:withProxy:saltForPtoG');
 
     do {
       generateTokens = this.generateAccessTokens(saltForGtoP, saltForPtoG);

+ 8 - 8
apps/app/src/server/models/user.js

@@ -101,13 +101,13 @@ const factory = (crowi) => {
   function decideUserStatusOnRegistration() {
     validateCrowi();
 
-    const isInstalled = configManager.getConfig('crowi', 'app:installed');
+    const isInstalled = configManager.getConfig('app:installed');
     if (!isInstalled) {
       return STATUS_ACTIVE; // is this ok?
     }
 
     // status decided depends on registrationMode
-    const registrationMode = configManager.getConfig('crowi', 'security:registrationMode');
+    const registrationMode = configManager.getConfig('security:registrationMode');
     switch (registrationMode) {
       case aclService.labels.SECURITY_REGISTRATION_MODE_OPEN:
         return STATUS_ACTIVE;
@@ -278,7 +278,7 @@ const factory = (crowi) => {
     this.name = name;
     this.username = username;
     this.status = STATUS_ACTIVE;
-    this.isEmailPublished = configManager.getConfig('crowi', 'customize:isEmailPublishedForNewUser');
+    this.isEmailPublished = configManager.getConfig('customize:isEmailPublishedForNewUser');
 
     this.save((err, userData) => {
       userEvent.emit('activated', userData);
@@ -371,7 +371,7 @@ const factory = (crowi) => {
   userSchema.statics.isEmailValid = function(email, callback) {
     validateCrowi();
 
-    const whitelist = configManager.getConfig('crowi', 'security:registrationWhitelist');
+    const whitelist = configManager.getConfig('security:registrationWhitelist');
 
     if (Array.isArray(whitelist) && whitelist.length > 0) {
       return whitelist.some((allowedEmail) => {
@@ -480,7 +480,7 @@ const factory = (crowi) => {
   };
 
   userSchema.statics.isUserCountExceedsUpperLimit = async function() {
-    const userUpperLimit = configManager.getConfig('crowi', 'security:userUpperLimit');
+    const userUpperLimit = configManager.getConfig('security:userUpperLimit');
 
     const activeUsers = await this.countActiveUsers();
     if (userUpperLimit <= activeUsers) {
@@ -576,7 +576,7 @@ const factory = (crowi) => {
     newUser.setPassword(password);
     newUser.status = STATUS_INVITED;
 
-    const globalLang = configManager.getConfig('crowi', 'app:globalLang');
+    const globalLang = configManager.getConfig('app:globalLang');
     if (globalLang != null) {
       newUser.lang = globalLang;
     }
@@ -651,9 +651,9 @@ const factory = (crowi) => {
     }
 
     // Default email show/hide is up to the administrator
-    newUser.isEmailPublished = configManager.getConfig('crowi', 'customize:isEmailPublishedForNewUser');
+    newUser.isEmailPublished = configManager.getConfig('customize:isEmailPublishedForNewUser');
 
-    const globalLang = configManager.getConfig('crowi', 'app:globalLang');
+    const globalLang = configManager.getConfig('app:globalLang');
     if (globalLang != null) {
       newUser.lang = globalLang;
     }

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

@@ -92,8 +92,8 @@ module.exports = (crowi) => {
       npmVersion: runtimeVersions.npm ?? '-',
       pnpmVersion: runtimeVersions.pnpm ?? '-',
       envVars: configManager.getManagedEnvVars(),
-      isV5Compatible: configManager.getConfig('crowi', 'app:isV5Compatible'),
-      isMaintenanceMode: configManager.getConfig('crowi', 'app:isMaintenanceMode'),
+      isV5Compatible: configManager.getConfig('app:isV5Compatible'),
+      isMaintenanceMode: configManager.getConfig('app:isMaintenanceMode'),
     };
 
     return res.apiv3({ adminHomeParams });

+ 72 - 72
apps/app/src/server/routes/apiv3/app-settings.js

@@ -432,53 +432,53 @@ module.exports = (crowi) => {
    */
   router.get('/', accessTokenParser, loginRequiredStrictly, adminRequired, async(req, res) => {
     const appSettingsParams = {
-      title: configManager.getConfig('crowi', 'app:title'),
-      confidential: configManager.getConfig('crowi', 'app:confidential'),
-      globalLang: configManager.getConfig('crowi', 'app:globalLang'),
-      isEmailPublishedForNewUser: configManager.getConfig('crowi', 'customize:isEmailPublishedForNewUser'),
-      fileUpload: configManager.getConfig('crowi', 'app:fileUpload'),
-      isV5Compatible: configManager.getConfig('crowi', 'app:isV5Compatible'),
-      siteUrl: configManager.getConfig('crowi', 'app:siteUrl'),
-      siteUrlUseOnlyEnvVars: configManager.getConfig('crowi', 'env:useOnlyEnvVars:app:siteUrl'),
+      title: configManager.getConfig('app:title'),
+      confidential: configManager.getConfig('app:confidential'),
+      globalLang: configManager.getConfig('app:globalLang'),
+      isEmailPublishedForNewUser: configManager.getConfig('customize:isEmailPublishedForNewUser'),
+      fileUpload: configManager.getConfig('app:fileUpload'),
+      isV5Compatible: configManager.getConfig('app:isV5Compatible'),
+      siteUrl: configManager.getConfig('app:siteUrl'),
+      siteUrlUseOnlyEnvVars: configManager.getConfig('env:useOnlyEnvVars:app:siteUrl'),
       envSiteUrl: configManager.getConfig('app:siteUrl', ConfigSource.env),
       isMailerSetup: crowi.mailService.isMailerSetup,
-      fromAddress: configManager.getConfig('crowi', 'mail:from'),
+      fromAddress: configManager.getConfig('mail:from'),
 
-      transmissionMethod: configManager.getConfig('crowi', 'mail:transmissionMethod'),
-      smtpHost: configManager.getConfig('crowi', 'mail:smtpHost'),
-      smtpPort: configManager.getConfig('crowi', 'mail:smtpPort'),
-      smtpUser: configManager.getConfig('crowi', 'mail:smtpUser'),
-      smtpPassword: configManager.getConfig('crowi', 'mail:smtpPassword'),
-      sesAccessKeyId: configManager.getConfig('crowi', 'mail:sesAccessKeyId'),
-      sesSecretAccessKey: configManager.getConfig('crowi', 'mail:sesSecretAccessKey'),
+      transmissionMethod: configManager.getConfig('mail:transmissionMethod'),
+      smtpHost: configManager.getConfig('mail:smtpHost'),
+      smtpPort: configManager.getConfig('mail:smtpPort'),
+      smtpUser: configManager.getConfig('mail:smtpUser'),
+      smtpPassword: configManager.getConfig('mail:smtpPassword'),
+      sesAccessKeyId: configManager.getConfig('mail:sesAccessKeyId'),
+      sesSecretAccessKey: configManager.getConfig('mail:sesSecretAccessKey'),
 
-      fileUploadType: configManager.getConfig('crowi', 'app:fileUploadType'),
+      fileUploadType: configManager.getConfig('app:fileUploadType'),
       envFileUploadType: configManager.getConfig('app:fileUploadType', ConfigSource.env),
-      useOnlyEnvVarForFileUploadType: configManager.getConfig('crowi', 'env:useOnlyEnvVars:app:fileUploadType'),
+      useOnlyEnvVarForFileUploadType: configManager.getConfig('env:useOnlyEnvVars:app:fileUploadType'),
 
-      s3Region: configManager.getConfig('crowi', 'aws:s3Region'),
-      s3CustomEndpoint: configManager.getConfig('crowi', 'aws:s3CustomEndpoint'),
-      s3Bucket: configManager.getConfig('crowi', 'aws:s3Bucket'),
-      s3AccessKeyId: configManager.getConfig('crowi', 'aws:s3AccessKeyId'),
-      s3ReferenceFileWithRelayMode: configManager.getConfig('crowi', 'aws:referenceFileWithRelayMode'),
+      s3Region: configManager.getConfig('aws:s3Region'),
+      s3CustomEndpoint: configManager.getConfig('aws:s3CustomEndpoint'),
+      s3Bucket: configManager.getConfig('aws:s3Bucket'),
+      s3AccessKeyId: configManager.getConfig('aws:s3AccessKeyId'),
+      s3ReferenceFileWithRelayMode: configManager.getConfig('aws:referenceFileWithRelayMode'),
 
-      gcsUseOnlyEnvVars: configManager.getConfig('crowi', 'env:useOnlyEnvVars:gcs'),
-      gcsApiKeyJsonPath: configManager.getConfig('crowi', 'gcs:apiKeyJsonPath'),
-      gcsBucket: configManager.getConfig('crowi', 'gcs:bucket'),
-      gcsUploadNamespace: configManager.getConfig('crowi', 'gcs:uploadNamespace'),
-      gcsReferenceFileWithRelayMode: configManager.getConfig('crowi', 'gcs:referenceFileWithRelayMode'),
+      gcsUseOnlyEnvVars: configManager.getConfig('env:useOnlyEnvVars:gcs'),
+      gcsApiKeyJsonPath: configManager.getConfig('gcs:apiKeyJsonPath'),
+      gcsBucket: configManager.getConfig('gcs:bucket'),
+      gcsUploadNamespace: configManager.getConfig('gcs:uploadNamespace'),
+      gcsReferenceFileWithRelayMode: configManager.getConfig('gcs:referenceFileWithRelayMode'),
 
       envGcsApiKeyJsonPath: configManager.getConfig('gcs:apiKeyJsonPath', ConfigSource.env),
       envGcsBucket: configManager.getConfig('gcs:bucket', ConfigSource.env),
       envGcsUploadNamespace: configManager.getConfig('gcs:uploadNamespace', ConfigSource.env),
 
-      azureUseOnlyEnvVars: configManager.getConfig('crowi', 'env:useOnlyEnvVars:azure'),
+      azureUseOnlyEnvVars: configManager.getConfig('env:useOnlyEnvVars:azure'),
       azureTenantId: configManager.getConfig('azure:tenantId', ConfigSource.db),
       azureClientId: configManager.getConfig('azure:clientId', ConfigSource.db),
       azureClientSecret: configManager.getConfig('azure:clientSecret', ConfigSource.db),
       azureStorageAccountName: configManager.getConfig('azure:storageAccountName', ConfigSource.db),
       azureStorageContainerName: configManager.getConfig('azure:storageContainerName', ConfigSource.db),
-      azureReferenceFileWithRelayMode: configManager.getConfig('crowi', 'azure:referenceFileWithRelayMode'),
+      azureReferenceFileWithRelayMode: configManager.getConfig('azure:referenceFileWithRelayMode'),
 
       envAzureTenantId: configManager.getConfig('azure:tenantId', ConfigSource.env),
       envAzureClientId: configManager.getConfig('azure:clientId', ConfigSource.env),
@@ -486,12 +486,12 @@ module.exports = (crowi) => {
       envAzureStorageAccountName: configManager.getConfig('azure:storageAccountName', ConfigSource.env),
       envAzureStorageContainerName: configManager.getConfig('azure:storageContainerName', ConfigSource.env),
 
-      isEnabledPlugins: configManager.getConfig('crowi', 'plugin:isEnabledPlugins'),
+      isEnabledPlugins: configManager.getConfig('plugin:isEnabledPlugins'),
 
-      isQuestionnaireEnabled: configManager.getConfig('crowi', 'questionnaire:isQuestionnaireEnabled'),
-      isAppSiteUrlHashed: configManager.getConfig('crowi', 'questionnaire:isAppSiteUrlHashed'),
+      isQuestionnaireEnabled: configManager.getConfig('questionnaire:isQuestionnaireEnabled'),
+      isAppSiteUrlHashed: configManager.getConfig('questionnaire:isAppSiteUrlHashed'),
 
-      isMaintenanceMode: configManager.getConfig('crowi', 'app:isMaintenanceMode'),
+      isMaintenanceMode: configManager.getConfig('app:isMaintenanceMode'),
     };
     return res.apiv3({ appSettingsParams });
 
@@ -539,11 +539,11 @@ module.exports = (crowi) => {
     try {
       await configManager.updateConfigs(requestAppSettingParams);
       const appSettingParams = {
-        title: configManager.getConfig('crowi', 'app:title'),
-        confidential: configManager.getConfig('crowi', 'app:confidential'),
-        globalLang: configManager.getConfig('crowi', 'app:globalLang'),
-        isEmailPublishedForNewUser: configManager.getConfig('crowi', 'customize:isEmailPublishedForNewUser'),
-        fileUpload: configManager.getConfig('crowi', 'app:fileUpload'),
+        title: configManager.getConfig('app:title'),
+        confidential: configManager.getConfig('app:confidential'),
+        globalLang: configManager.getConfig('app:globalLang'),
+        isEmailPublishedForNewUser: configManager.getConfig('customize:isEmailPublishedForNewUser'),
+        fileUpload: configManager.getConfig('app:fileUpload'),
       };
 
       const parameters = { action: SupportedAction.ACTION_ADMIN_APP_SETTINGS_UPDATE };
@@ -594,7 +594,7 @@ module.exports = (crowi) => {
    */
   router.put('/site-url-setting', loginRequiredStrictly, adminRequired, addActivity, validator.siteUrlSetting, apiV3FormValidator, async(req, res) => {
 
-    const useOnlyEnvVars = configManager.getConfig('crowi', 'env:useOnlyEnvVars:app:siteUrl');
+    const useOnlyEnvVars = configManager.getConfig('env:useOnlyEnvVars:app:siteUrl');
 
     if (useOnlyEnvVars) {
       const msg = 'Updating the Site URL is prohibited on this system.';
@@ -608,7 +608,7 @@ module.exports = (crowi) => {
     try {
       await configManager.updateConfigs(requestSiteUrlSettingParams);
       const siteUrlSettingParams = {
-        siteUrl: configManager.getConfig('crowi', 'app:siteUrl'),
+        siteUrl: configManager.getConfig('app:siteUrl'),
       };
 
       const parameters = { action: SupportedAction.ACTION_ADMIN_SITE_URL_UPDATE };
@@ -650,15 +650,15 @@ module.exports = (crowi) => {
       throw Error('mailService is not setup');
     }
 
-    const fromAddress = configManager.getConfig('crowi', 'mail:from');
+    const fromAddress = configManager.getConfig('mail:from');
     if (fromAddress == null) {
       throw Error('fromAddress is not setup');
     }
 
-    const smtpHost = configManager.getConfig('crowi', 'mail:smtpHost');
-    const smtpPort = configManager.getConfig('crowi', 'mail:smtpPort');
-    const smtpUser = configManager.getConfig('crowi', 'mail:smtpUser');
-    const smtpPassword = configManager.getConfig('crowi', 'mail:smtpPassword');
+    const smtpHost = configManager.getConfig('mail:smtpHost');
+    const smtpPort = configManager.getConfig('mail:smtpPort');
+    const smtpUser = configManager.getConfig('mail:smtpUser');
+    const smtpPassword = configManager.getConfig('mail:smtpPassword');
 
     const option = {
       host: smtpHost,
@@ -700,13 +700,13 @@ module.exports = (crowi) => {
 
     return {
       isMailerSetup: mailService.isMailerSetup,
-      fromAddress: configManager.getConfig('crowi', 'mail:from'),
-      smtpHost: configManager.getConfig('crowi', 'mail:smtpHost'),
-      smtpPort: configManager.getConfig('crowi', 'mail:smtpPort'),
-      smtpUser: configManager.getConfig('crowi', 'mail:smtpUser'),
-      smtpPassword: configManager.getConfig('crowi', 'mail:smtpPassword'),
-      sesAccessKeyId: configManager.getConfig('crowi', 'mail:sesAccessKeyId'),
-      sesSecretAccessKey: configManager.getConfig('crowi', 'mail:sesSecretAccessKey'),
+      fromAddress: configManager.getConfig('mail:from'),
+      smtpHost: configManager.getConfig('mail:smtpHost'),
+      smtpPort: configManager.getConfig('mail:smtpPort'),
+      smtpUser: configManager.getConfig('mail:smtpUser'),
+      smtpPassword: configManager.getConfig('mail:smtpPassword'),
+      sesAccessKeyId: configManager.getConfig('mail:sesAccessKeyId'),
+      sesSecretAccessKey: configManager.getConfig('mail:sesSecretAccessKey'),
     };
   };
 
@@ -924,31 +924,31 @@ module.exports = (crowi) => {
       crowi.fileUploaderSwitchService.publishUpdatedMessage();
 
       const responseParams = {
-        fileUploadType: configManager.getConfig('crowi', 'app:fileUploadType'),
+        fileUploadType: configManager.getConfig('app:fileUploadType'),
       };
 
       if (fileUploadType === 'gcs') {
-        responseParams.gcsApiKeyJsonPath = configManager.getConfig('crowi', 'gcs:apiKeyJsonPath');
-        responseParams.gcsBucket = configManager.getConfig('crowi', 'gcs:bucket');
-        responseParams.gcsUploadNamespace = configManager.getConfig('crowi', 'gcs:uploadNamespace');
-        responseParams.gcsReferenceFileWithRelayMode = configManager.getConfig('crowi', 'gcs:referenceFileWithRelayMode ');
+        responseParams.gcsApiKeyJsonPath = configManager.getConfig('gcs:apiKeyJsonPath');
+        responseParams.gcsBucket = configManager.getConfig('gcs:bucket');
+        responseParams.gcsUploadNamespace = configManager.getConfig('gcs:uploadNamespace');
+        responseParams.gcsReferenceFileWithRelayMode = configManager.getConfig('gcs:referenceFileWithRelayMode ');
       }
 
       if (fileUploadType === 'aws') {
-        responseParams.s3Region = configManager.getConfig('crowi', 'aws:s3Region');
-        responseParams.s3CustomEndpoint = configManager.getConfig('crowi', 'aws:s3CustomEndpoint');
-        responseParams.s3Bucket = configManager.getConfig('crowi', 'aws:s3Bucket');
-        responseParams.s3AccessKeyId = configManager.getConfig('crowi', 'aws:s3AccessKeyId');
-        responseParams.s3ReferenceFileWithRelayMode = configManager.getConfig('crowi', 'aws:referenceFileWithRelayMode');
+        responseParams.s3Region = configManager.getConfig('aws:s3Region');
+        responseParams.s3CustomEndpoint = configManager.getConfig('aws:s3CustomEndpoint');
+        responseParams.s3Bucket = configManager.getConfig('aws:s3Bucket');
+        responseParams.s3AccessKeyId = configManager.getConfig('aws:s3AccessKeyId');
+        responseParams.s3ReferenceFileWithRelayMode = configManager.getConfig('aws:referenceFileWithRelayMode');
       }
 
       if (fileUploadType === 'azure') {
-        responseParams.azureTenantId = configManager.getConfig('crowi', 'azure:tenantId');
-        responseParams.azureClientId = configManager.getConfig('crowi', 'azure:clientId');
-        responseParams.azureClientSecret = configManager.getConfig('crowi', 'azure:clientSecret');
-        responseParams.azureStorageAccountName = configManager.getConfig('crowi', 'azure:storageAccountName');
-        responseParams.azureStorageContainerName = configManager.getConfig('crowi', 'azure:storageContainerName');
-        responseParams.azureReferenceFileWithRelayMode = configManager.getConfig('crowi', 'azure:referenceFileWithRelayMode');
+        responseParams.azureTenantId = configManager.getConfig('azure:tenantId');
+        responseParams.azureClientId = configManager.getConfig('azure:clientId');
+        responseParams.azureClientSecret = configManager.getConfig('azure:clientSecret');
+        responseParams.azureStorageAccountName = configManager.getConfig('azure:storageAccountName');
+        responseParams.azureStorageContainerName = configManager.getConfig('azure:storageContainerName');
+        responseParams.azureReferenceFileWithRelayMode = configManager.getConfig('azure:referenceFileWithRelayMode');
       }
       const parameters = { action: SupportedAction.ACTION_ADMIN_FILE_UPLOAD_CONFIG_UPDATE };
       activityEvent.emit('update', res.locals.activity._id, parameters);
@@ -1004,8 +1004,8 @@ module.exports = (crowi) => {
       await configManager.updateConfigs(requestParams, { skipPubsub: true });
 
       const responseParams = {
-        isQuestionnaireEnabled: configManager.getConfig('crowi', 'questionnaire:isQuestionnaireEnabled'),
-        isAppSiteUrlHashed: configManager.getConfig('crowi', 'questionnaire:isAppSiteUrlHashed'),
+        isQuestionnaireEnabled: configManager.getConfig('questionnaire:isQuestionnaireEnabled'),
+        isAppSiteUrlHashed: configManager.getConfig('questionnaire:isAppSiteUrlHashed'),
       };
 
       const parameters = { action: SupportedAction.ACTION_ADMIN_QUESTIONNAIRE_SETTINGS_UPDATE };
@@ -1050,7 +1050,7 @@ module.exports = (crowi) => {
       return res.apiv3Err(new ErrorV3('GROWI is not maintenance mode. To import data, please activate the maintenance mode first.', 'not_maintenance_mode'));
     }
 
-    const isV5Compatible = configManager.getConfig('crowi', 'app:isV5Compatible');
+    const isV5Compatible = configManager.getConfig('app:isV5Compatible');
 
     try {
       if (!isV5Compatible) {

+ 1 - 1
apps/app/src/server/routes/apiv3/attachment.js

@@ -199,7 +199,7 @@ module.exports = (crowi) => {
    */
   router.get('/list', accessTokenParser, loginRequired, validator.retrieveAttachments, apiV3FormValidator, async(req, res) => {
 
-    const limit = req.query.limit || await crowi.configManager.getConfig('crowi', 'customize:showPageLimitationS') || 10;
+    const limit = req.query.limit || await crowi.configManager.getConfig('customize:showPageLimitationS') || 10;
     const pageNumber = req.query.pageNumber || 1;
     const offset = (pageNumber - 1) * limit;
 

+ 41 - 41
apps/app/src/server/routes/apiv3/customize-setting.js

@@ -170,22 +170,22 @@ module.exports = (crowi) => {
    */
   router.get('/', loginRequiredStrictly, adminRequired, async(req, res) => {
     const customizeParams = {
-      isEnabledTimeline: await configManager.getConfig('crowi', 'customize:isEnabledTimeline'),
-      isEnabledAttachTitleHeader: await configManager.getConfig('crowi', 'customize:isEnabledAttachTitleHeader'),
-      pageLimitationS: await configManager.getConfig('crowi', 'customize:showPageLimitationS'),
-      pageLimitationM: await configManager.getConfig('crowi', 'customize:showPageLimitationM'),
-      pageLimitationL: await configManager.getConfig('crowi', 'customize:showPageLimitationL'),
-      pageLimitationXL: await configManager.getConfig('crowi', 'customize:showPageLimitationXL'),
-      isEnabledStaleNotification: await configManager.getConfig('crowi', 'customize:isEnabledStaleNotification'),
-      isAllReplyShown: await configManager.getConfig('crowi', 'customize:isAllReplyShown'),
-      isSearchScopeChildrenAsDefault: await configManager.getConfig('crowi', 'customize:isSearchScopeChildrenAsDefault'),
-      isEnabledMarp: await configManager.getConfig('crowi', 'customize:isEnabledMarp'),
-      styleName: await configManager.getConfig('crowi', 'customize:highlightJsStyle'),
-      styleBorder: await configManager.getConfig('crowi', 'customize:highlightJsStyleBorder'),
-      customizeTitle: await configManager.getConfig('crowi', 'customize:title'),
-      customizeScript: await configManager.getConfig('crowi', 'customize:script'),
-      customizeCss: await configManager.getConfig('crowi', 'customize:css'),
-      customizeNoscript: await configManager.getConfig('crowi', 'customize:noscript'),
+      isEnabledTimeline: await configManager.getConfig('customize:isEnabledTimeline'),
+      isEnabledAttachTitleHeader: await configManager.getConfig('customize:isEnabledAttachTitleHeader'),
+      pageLimitationS: await configManager.getConfig('customize:showPageLimitationS'),
+      pageLimitationM: await configManager.getConfig('customize:showPageLimitationM'),
+      pageLimitationL: await configManager.getConfig('customize:showPageLimitationL'),
+      pageLimitationXL: await configManager.getConfig('customize:showPageLimitationXL'),
+      isEnabledStaleNotification: await configManager.getConfig('customize:isEnabledStaleNotification'),
+      isAllReplyShown: await configManager.getConfig('customize:isAllReplyShown'),
+      isSearchScopeChildrenAsDefault: await configManager.getConfig('customize:isSearchScopeChildrenAsDefault'),
+      isEnabledMarp: await configManager.getConfig('customize:isEnabledMarp'),
+      styleName: await configManager.getConfig('customize:highlightJsStyle'),
+      styleBorder: await configManager.getConfig('customize:highlightJsStyleBorder'),
+      customizeTitle: await configManager.getConfig('customize:title'),
+      customizeScript: await configManager.getConfig('customize:script'),
+      customizeCss: await configManager.getConfig('customize:css'),
+      customizeNoscript: await configManager.getConfig('customize:noscript'),
     };
 
     return res.apiv3({ customizeParams });
@@ -211,7 +211,7 @@ module.exports = (crowi) => {
   router.get('/layout', loginRequiredStrictly, adminRequired, async(req, res) => {
 
     try {
-      const isContainerFluid = await configManager.getConfig('crowi', 'customize:isContainerFluid');
+      const isContainerFluid = await configManager.getConfig('customize:isContainerFluid');
       return res.apiv3({ isContainerFluid });
     }
     catch (err) {
@@ -252,7 +252,7 @@ module.exports = (crowi) => {
     try {
       await configManager.updateConfigs(requestParams);
       const customizedParams = {
-        isContainerFluid: await configManager.getConfig('crowi', 'customize:isContainerFluid'),
+        isContainerFluid: await configManager.getConfig('customize:isContainerFluid'),
       };
 
       const parameters = { action: SupportedAction.ACTION_ADMIN_LAYOUT_UPDATE };
@@ -270,7 +270,7 @@ module.exports = (crowi) => {
   router.get('/theme', loginRequiredStrictly, async(req, res) => {
 
     try {
-      const currentTheme = await configManager.getConfig('crowi', 'customize:theme');
+      const currentTheme = await configManager.getConfig('customize:theme');
 
       // retrieve plugin manifests
       const themePlugins = await GrowiPlugin.findEnabledPluginsByType(GrowiPluginType.Theme);
@@ -319,7 +319,7 @@ module.exports = (crowi) => {
     try {
       await configManager.updateConfigs(requestParams);
       const customizedParams = {
-        theme: await configManager.getConfig('crowi', 'customize:theme'),
+        theme: await configManager.getConfig('customize:theme'),
       };
       customizeService.initGrowiTheme();
       const parameters = { action: SupportedAction.ACTION_ADMIN_THEME_UPDATE };
@@ -337,8 +337,8 @@ module.exports = (crowi) => {
   router.get('/sidebar', loginRequiredStrictly, adminRequired, async(req, res) => {
 
     try {
-      const isSidebarCollapsedMode = await configManager.getConfig('crowi', 'customize:isSidebarCollapsedMode');
-      const isSidebarClosedAtDockMode = await configManager.getConfig('crowi', 'customize:isSidebarClosedAtDockMode');
+      const isSidebarCollapsedMode = await configManager.getConfig('customize:isSidebarCollapsedMode');
+      const isSidebarClosedAtDockMode = await configManager.getConfig('customize:isSidebarClosedAtDockMode');
       return res.apiv3({ isSidebarCollapsedMode, isSidebarClosedAtDockMode });
     }
     catch (err) {
@@ -357,8 +357,8 @@ module.exports = (crowi) => {
     try {
       await configManager.updateConfigs(requestParams);
       const customizedParams = {
-        isSidebarCollapsedMode: await configManager.getConfig('crowi', 'customize:isSidebarCollapsedMode'),
-        isSidebarClosedAtDockMode: await configManager.getConfig('crowi', 'customize:isSidebarClosedAtDockMode'),
+        isSidebarCollapsedMode: await configManager.getConfig('customize:isSidebarCollapsedMode'),
+        isSidebarClosedAtDockMode: await configManager.getConfig('customize:isSidebarClosedAtDockMode'),
       };
 
       activityEvent.emit('update', res.locals.activity._id, { action: SupportedAction.ACTION_ADMIN_SIDEBAR_UPDATE });
@@ -411,15 +411,15 @@ module.exports = (crowi) => {
     try {
       await configManager.updateConfigs(requestParams);
       const customizedParams = {
-        isEnabledTimeline: await configManager.getConfig('crowi', 'customize:isEnabledTimeline'),
-        isEnabledAttachTitleHeader: await configManager.getConfig('crowi', 'customize:isEnabledAttachTitleHeader'),
-        pageLimitationS: await configManager.getConfig('crowi', 'customize:showPageLimitationS'),
-        pageLimitationM: await configManager.getConfig('crowi', 'customize:showPageLimitationM'),
-        pageLimitationL: await configManager.getConfig('crowi', 'customize:showPageLimitationL'),
-        pageLimitationXL: await configManager.getConfig('crowi', 'customize:showPageLimitationXL'),
-        isEnabledStaleNotification: await configManager.getConfig('crowi', 'customize:isEnabledStaleNotification'),
-        isAllReplyShown: await configManager.getConfig('crowi', 'customize:isAllReplyShown'),
-        isSearchScopeChildrenAsDefault: await configManager.getConfig('crowi', 'customize:isSearchScopeChildrenAsDefault'),
+        isEnabledTimeline: await configManager.getConfig('customize:isEnabledTimeline'),
+        isEnabledAttachTitleHeader: await configManager.getConfig('customize:isEnabledAttachTitleHeader'),
+        pageLimitationS: await configManager.getConfig('customize:showPageLimitationS'),
+        pageLimitationM: await configManager.getConfig('customize:showPageLimitationM'),
+        pageLimitationL: await configManager.getConfig('customize:showPageLimitationL'),
+        pageLimitationXL: await configManager.getConfig('customize:showPageLimitationXL'),
+        isEnabledStaleNotification: await configManager.getConfig('customize:isEnabledStaleNotification'),
+        isAllReplyShown: await configManager.getConfig('customize:isAllReplyShown'),
+        isSearchScopeChildrenAsDefault: await configManager.getConfig('customize:isSearchScopeChildrenAsDefault'),
       };
       const parameters = { action: SupportedAction.ACTION_ADMIN_FUNCTION_UPDATE };
       activityEvent.emit('update', res.locals.activity._id, parameters);
@@ -441,7 +441,7 @@ module.exports = (crowi) => {
     try {
       await configManager.updateConfigs(requestParams);
       const customizedParams = {
-        isEnabledMarp: await configManager.getConfig('crowi', 'customize:isEnabledMarp'),
+        isEnabledMarp: await configManager.getConfig('customize:isEnabledMarp'),
       };
       const parameters = { action: SupportedAction.ACTION_ADMIN_FUNCTION_UPDATE };
       activityEvent.emit('update', res.locals.activity._id, parameters);
@@ -486,8 +486,8 @@ module.exports = (crowi) => {
     try {
       await configManager.updateConfigs(requestParams);
       const customizedParams = {
-        styleName: await configManager.getConfig('crowi', 'customize:highlightJsStyle'),
-        styleBorder: await configManager.getConfig('crowi', 'customize:highlightJsStyleBorder'),
+        styleName: await configManager.getConfig('customize:highlightJsStyle'),
+        styleBorder: await configManager.getConfig('customize:highlightJsStyleBorder'),
       };
       const parameters = { action: SupportedAction.ACTION_ADMIN_CODE_HIGHLIGHT_UPDATE };
       activityEvent.emit('update', res.locals.activity._id, parameters);
@@ -533,7 +533,7 @@ module.exports = (crowi) => {
       crowi.customizeService.publishUpdatedMessage();
 
       const customizedParams = {
-        customizeTitle: await configManager.getConfig('crowi', 'customize:title'),
+        customizeTitle: await configManager.getConfig('customize:title'),
       };
       customizeService.initCustomTitle();
       const parameters = { action: SupportedAction.ACTION_ADMIN_CUSTOM_TITLE_UPDATE };
@@ -577,7 +577,7 @@ module.exports = (crowi) => {
     try {
       await configManager.updateConfigs(requestParams);
       const customizedParams = {
-        customizeNoscript: await configManager.getConfig('crowi', 'customize:noscript'),
+        customizeNoscript: await configManager.getConfig('customize:noscript'),
       };
       const parameters = { action: SupportedAction.ACTION_ADMIN_CUSTOM_NOSCRIPT_UPDATE };
       activityEvent.emit('update', res.locals.activity._id, parameters);
@@ -622,7 +622,7 @@ module.exports = (crowi) => {
       crowi.customizeService.publishUpdatedMessage();
 
       const customizedParams = {
-        customizeCss: await configManager.getConfig('crowi', 'customize:css'),
+        customizeCss: await configManager.getConfig('customize:css'),
       };
       customizeService.initCustomCss();
       const parameters = { action: SupportedAction.ACTION_ADMIN_CUSTOM_CSS_UPDATE };
@@ -666,7 +666,7 @@ module.exports = (crowi) => {
     try {
       await configManager.updateConfigs(requestParams);
       const customizedParams = {
-        customizeScript: await configManager.getConfig('crowi', 'customize:script'),
+        customizeScript: await configManager.getConfig('customize:script'),
       };
       const parameters = { action: SupportedAction.ACTION_ADMIN_CUSTOM_SCRIPT_UPDATE };
       activityEvent.emit('update', res.locals.activity._id, parameters);
@@ -691,7 +691,7 @@ module.exports = (crowi) => {
     try {
       await configManager.updateConfigs(requestParams);
       const customizedParams = {
-        isDefaultLogo: await configManager.getConfig('crowi', 'customize:isDefaultLogo'),
+        isDefaultLogo: await configManager.getConfig('customize:isDefaultLogo'),
       };
       return res.apiv3({ customizedParams });
     }

+ 3 - 3
apps/app/src/server/routes/apiv3/forgot-password.js

@@ -30,7 +30,7 @@ module.exports = (crowi) => {
 
   const activityEvent = crowi.event('activity');
 
-  const minPasswordLength = configManager.getConfig('crowi', 'app:minPasswordLength');
+  const minPasswordLength = configManager.getConfig('app:minPasswordLength');
 
   const validator = {
     password: [
@@ -71,7 +71,7 @@ module.exports = (crowi) => {
 
   router.post('/', checkPassportStrategyMiddleware, validator.email, apiV3FormValidator, addActivity, async(req, res) => {
     const { email } = req.body;
-    const locale = configManager.getConfig('crowi', 'app:globalLang');
+    const locale = configManager.getConfig('app:globalLang');
     const appUrl = appService.getSiteUrl();
 
     try {
@@ -107,7 +107,7 @@ module.exports = (crowi) => {
   router.put('/', checkPassportStrategyMiddleware, injectResetOrderByTokenMiddleware, validator.password, apiV3FormValidator, addActivity, async(req, res) => {
     const { passwordResetOrder } = req;
     const { email } = passwordResetOrder;
-    const grobalLang = configManager.getConfig('crowi', 'app:globalLang');
+    const grobalLang = configManager.getConfig('app:globalLang');
     const i18n = grobalLang || req.language;
     const { newPassword } = req.body;
 

+ 5 - 5
apps/app/src/server/routes/apiv3/import.js

@@ -118,10 +118,10 @@ export default function route(crowi) {
   router.get('/', accessTokenParser, loginRequired, adminRequired, async(req, res) => {
     try {
       const importSettingsParams = {
-        esaTeamName: await crowi.configManager.getConfig('crowi', 'importer:esa:team_name'),
-        esaAccessToken: await crowi.configManager.getConfig('crowi', 'importer:esa:access_token'),
-        qiitaTeamName: await crowi.configManager.getConfig('crowi', 'importer:qiita:team_name'),
-        qiitaAccessToken: await crowi.configManager.getConfig('crowi', 'importer:qiita:access_token'),
+        esaTeamName: await crowi.configManager.getConfig('importer:esa:team_name'),
+        esaAccessToken: await crowi.configManager.getConfig('importer:esa:access_token'),
+        qiitaTeamName: await crowi.configManager.getConfig('importer:qiita:team_name'),
+        qiitaAccessToken: await crowi.configManager.getConfig('importer:qiita:access_token'),
       };
       return res.apiv3({
         importSettingsParams,
@@ -201,7 +201,7 @@ export default function route(crowi) {
     const { fileName, collections, options } = req.body;
 
     // pages collection can only be imported by upsert if isV5Compatible is true
-    const isV5Compatible = crowi.configManager.getConfig('crowi', 'app:isV5Compatible');
+    const isV5Compatible = crowi.configManager.getConfig('app:isV5Compatible');
     const isImportPagesCollection = collections.includes('pages');
     if (isV5Compatible && isImportPagesCollection) {
       /** @type {ImportOptionForPages} */

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

@@ -22,8 +22,8 @@ const routerForAdmin = express.Router();
 const routerForAuth = express.Router();
 
 module.exports = (crowi, app) => {
-  const isInstalled = crowi.configManager.getConfig('crowi', 'app:installed');
-  const minPasswordLength = crowi.configManager.getConfig('crowi', 'app:minPasswordLength');
+  const isInstalled = crowi.configManager.getConfig('app:installed');
+  const minPasswordLength = crowi.configManager.getConfig('app:minPasswordLength');
 
   // add custom functions to express response
   require('./response')(express, crowi);

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

@@ -27,7 +27,7 @@ module.exports = (crowi: Crowi): Router => {
 
   const router = express.Router();
 
-  const minPasswordLength = configManager.getConfig('crowi', 'app:minPasswordLength');
+  const minPasswordLength = configManager.getConfig('app:minPasswordLength');
 
   // eslint-disable-next-line max-len
   router.post('/', registerRules(minPasswordLength), registerValidation, addActivity, async(req: FormRequest, res: ApiV3Response) => {

+ 16 - 16
apps/app/src/server/routes/apiv3/markdown-setting.js

@@ -111,14 +111,14 @@ module.exports = (crowi) => {
    */
   router.get('/', loginRequiredStrictly, adminRequired, async(req, res) => {
     const markdownParams = {
-      isEnabledLinebreaks: await crowi.configManager.getConfig('markdown', 'markdown:isEnabledLinebreaks'),
-      isEnabledLinebreaksInComments: await crowi.configManager.getConfig('markdown', 'markdown:isEnabledLinebreaksInComments'),
-      adminPreferredIndentSize: await crowi.configManager.getConfig('markdown', 'markdown:adminPreferredIndentSize'),
-      isIndentSizeForced: await crowi.configManager.getConfig('markdown', 'markdown:isIndentSizeForced'),
-      isEnabledXss: await crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:isEnabledPrevention'),
-      xssOption: await crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:option'),
-      tagWhitelist: await crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:tagNames'),
-      attrWhitelist: await crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes'),
+      isEnabledLinebreaks: await crowi.configManager.getConfig('markdown:isEnabledLinebreaks'),
+      isEnabledLinebreaksInComments: await crowi.configManager.getConfig('markdown:isEnabledLinebreaksInComments'),
+      adminPreferredIndentSize: await crowi.configManager.getConfig('markdown:adminPreferredIndentSize'),
+      isIndentSizeForced: await crowi.configManager.getConfig('markdown:isIndentSizeForced'),
+      isEnabledXss: await crowi.configManager.getConfig('markdown:rehypeSanitize:isEnabledPrevention'),
+      xssOption: await crowi.configManager.getConfig('markdown:rehypeSanitize:option'),
+      tagWhitelist: await crowi.configManager.getConfig('markdown:rehypeSanitize:tagNames'),
+      attrWhitelist: await crowi.configManager.getConfig('markdown:rehypeSanitize:attributes'),
     };
 
     return res.apiv3({ markdownParams });
@@ -157,8 +157,8 @@ module.exports = (crowi) => {
     try {
       await configManager.updateConfigs(requestLineBreakParams);
       const lineBreaksParams = {
-        isEnabledLinebreaks: await crowi.configManager.getConfig('markdown', 'markdown:isEnabledLinebreaks'),
-        isEnabledLinebreaksInComments: await crowi.configManager.getConfig('markdown', 'markdown:isEnabledLinebreaksInComments'),
+        isEnabledLinebreaks: await crowi.configManager.getConfig('markdown:isEnabledLinebreaks'),
+        isEnabledLinebreaksInComments: await crowi.configManager.getConfig('markdown:isEnabledLinebreaksInComments'),
       };
 
       const parameters = { action: SupportedAction.ACTION_ADMIN_MARKDOWN_LINE_BREAK_UPDATE };
@@ -184,8 +184,8 @@ module.exports = (crowi) => {
     try {
       await configManager.updateConfigs(requestIndentParams);
       const indentParams = {
-        adminPreferredIndentSize: await crowi.configManager.getConfig('markdown', 'markdown:adminPreferredIndentSize'),
-        isIndentSizeForced: await crowi.configManager.getConfig('markdown', 'markdown:isIndentSizeForced'),
+        adminPreferredIndentSize: await crowi.configManager.getConfig('markdown:adminPreferredIndentSize'),
+        isIndentSizeForced: await crowi.configManager.getConfig('markdown:isIndentSizeForced'),
       };
 
       const parameters = { action: SupportedAction.ACTION_ADMIN_MARKDOWN_INDENT_UPDATE };
@@ -248,10 +248,10 @@ module.exports = (crowi) => {
     try {
       await configManager.updateConfigs(reqestXssParams);
       const xssParams = {
-        isEnabledXss: await crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:isEnabledPrevention'),
-        xssOption: await crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:option'),
-        tagWhitelist: await crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:tagNames'),
-        attrWhitelist: await crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes'),
+        isEnabledXss: await crowi.configManager.getConfig('markdown:rehypeSanitize:isEnabledPrevention'),
+        xssOption: await crowi.configManager.getConfig('markdown:rehypeSanitize:option'),
+        tagWhitelist: await crowi.configManager.getConfig('markdown:rehypeSanitize:tagNames'),
+        attrWhitelist: await crowi.configManager.getConfig('markdown:rehypeSanitize:attributes'),
       };
 
       const parameters = { action: SupportedAction.ACTION_ADMIN_MARKDOWN_XSS_UPDATE };

+ 5 - 5
apps/app/src/server/routes/apiv3/notification-setting.js

@@ -122,11 +122,11 @@ module.exports = (crowi) => {
       // status of slack intagration
       isSlackbotConfigured: crowi.slackIntegrationService.isSlackbotConfigured,
       isSlackLegacyConfigured: crowi.slackIntegrationService.isSlackLegacyConfigured,
-      currentBotType: await crowi.configManager.getConfig('crowi', 'slackbot:currentBotType'),
+      currentBotType: await crowi.configManager.getConfig('slackbot:currentBotType'),
 
       userNotifications: await UpdatePost.findAll(),
-      isNotificationForOwnerPageEnabled: await crowi.configManager.getConfig('notification', 'notification:owner-page:isEnabled'),
-      isNotificationForGroupPageEnabled: await crowi.configManager.getConfig('notification', 'notification:group-page:isEnabled'),
+      isNotificationForOwnerPageEnabled: await crowi.configManager.getConfig('notification:owner-page:isEnabled'),
+      isNotificationForGroupPageEnabled: await crowi.configManager.getConfig('notification:group-page:isEnabled'),
       globalNotifications: await GlobalNotificationSetting.findAll(),
     };
     return res.apiv3({ notificationParams });
@@ -427,8 +427,8 @@ module.exports = (crowi) => {
     try {
       await configManager.updateConfigs(requestParams);
       const responseParams = {
-        isNotificationForOwnerPageEnabled: await crowi.configManager.getConfig('notification', 'notification:owner-page:isEnabled'),
-        isNotificationForGroupPageEnabled: await crowi.configManager.getConfig('notification', 'notification:group-page:isEnabled'),
+        isNotificationForOwnerPageEnabled: await crowi.configManager.getConfig('notification:owner-page:isEnabled'),
+        isNotificationForGroupPageEnabled: await crowi.configManager.getConfig('notification:group-page:isEnabled'),
       };
 
       const parameters = { action: SupportedAction.ACTION_ADMIN_NOTIFICATION_GRANT_SETTINGS_UPDATE };

+ 2 - 2
apps/app/src/server/routes/apiv3/page-listing.ts

@@ -105,8 +105,8 @@ const routerFactory = (crowi: Crowi): Router => {
 
     const pageService = crowi.pageService;
 
-    const hideRestrictedByOwner = await configManager.getConfig('crowi', 'security:list-policy:hideRestrictedByOwner');
-    const hideRestrictedByGroup = await configManager.getConfig('crowi', 'security:list-policy:hideRestrictedByGroup');
+    const hideRestrictedByOwner = await configManager.getConfig('security:list-policy:hideRestrictedByOwner');
+    const hideRestrictedByGroup = await configManager.getConfig('security:list-policy:hideRestrictedByGroup');
 
     try {
       const pages = await pageService.findChildrenByParentPathOrIdAndViewer(

+ 1 - 1
apps/app/src/server/routes/apiv3/page/create-page.ts

@@ -135,7 +135,7 @@ export const createPageHandlersFactory: CreatePageHandlersFactory = (crowi) => {
     let tags: string[] = _tags ?? [];
 
     if (_body == null) {
-      const isEnabledAttachTitleHeader = await configManager.getConfig('crowi', 'customize:isEnabledAttachTitleHeader');
+      const isEnabledAttachTitleHeader = await configManager.getConfig('customize:isEnabledAttachTitleHeader');
       if (isEnabledAttachTitleHeader) {
         body += `${attachTitleHeader(path)}\n`;
       }

+ 1 - 1
apps/app/src/server/routes/apiv3/page/index.ts

@@ -884,7 +884,7 @@ module.exports = (crowi) => {
       const { pageId } = req.params;
       const { expandContentWidth } = req.body;
 
-      const isContainerFluidBySystem = configManager.getConfig('crowi', 'customize:isContainerFluid');
+      const isContainerFluidBySystem = configManager.getConfig('customize:isContainerFluid');
 
       try {
         const updateQuery = expandContentWidth === isContainerFluidBySystem

+ 4 - 4
apps/app/src/server/routes/apiv3/pages/index.js

@@ -139,8 +139,8 @@ module.exports = (crowi) => {
     const offset = parseInt(req.query.offset) || 0;
     const includeWipPage = req.query.includeWipPage === 'true'; // Need validation using express-validator
 
-    const hideRestrictedByOwner = await crowi.configManager.getConfig('crowi', 'security:list-policy:hideRestrictedByOwner');
-    const hideRestrictedByGroup = await crowi.configManager.getConfig('crowi', 'security:list-policy:hideRestrictedByGroup');
+    const hideRestrictedByOwner = await crowi.configManager.getConfig('security:list-policy:hideRestrictedByOwner');
+    const hideRestrictedByGroup = await crowi.configManager.getConfig('security:list-policy:hideRestrictedByGroup');
 
     /**
     * @type {import('~/server/models/page').FindRecentUpdatedPagesOption}
@@ -426,7 +426,7 @@ module.exports = (crowi) => {
   router.get('/list', accessTokenParser, loginRequired, validator.displayList, apiV3FormValidator, async(req, res) => {
 
     const { path } = req.query;
-    const limit = parseInt(req.query.limit) || await crowi.configManager.getConfig('crowi', 'customize:showPageLimitationS') || 10;
+    const limit = parseInt(req.query.limit) || await crowi.configManager.getConfig('customize:showPageLimitationS') || 10;
     const page = req.query.page || 1;
     const offset = (page - 1) * limit;
 
@@ -719,7 +719,7 @@ module.exports = (crowi) => {
 
   router.get('/v5-migration-status', accessTokenParser, loginRequired, async(req, res) => {
     try {
-      const isV5Compatible = crowi.configManager.getConfig('crowi', 'app:isV5Compatible');
+      const isV5Compatible = crowi.configManager.getConfig('app:isV5Compatible');
       const migratablePagesCount = req.user != null ? await crowi.pageService.countPagesCanNormalizeParentByUser(req.user) : null; // null check since not using loginRequiredStrictly
       return res.apiv3({ isV5Compatible, migratablePagesCount });
     }

+ 2 - 2
apps/app/src/server/routes/apiv3/personal-setting.js

@@ -74,7 +74,7 @@ module.exports = (crowi) => {
 
   const activityEvent = crowi.event('activity');
 
-  const minPasswordLength = crowi.configManager.getConfig('crowi', 'app:minPasswordLength');
+  const minPasswordLength = crowi.configManager.getConfig('app:minPasswordLength');
 
   const validator = {
     personal: [
@@ -189,7 +189,7 @@ module.exports = (crowi) => {
     try {
       const user = await User.findUserByUsername(username);
       const isPasswordSet = user.isPasswordSet();
-      const minPasswordLength = crowi.configManager.getConfig('crowi', 'app:minPasswordLength');
+      const minPasswordLength = crowi.configManager.getConfig('app:minPasswordLength');
       return res.apiv3({ isPasswordSet, minPasswordLength });
     }
     catch (err) {

+ 1 - 1
apps/app/src/server/routes/apiv3/revisions.js

@@ -87,7 +87,7 @@ module.exports = (crowi) => {
 
   router.get('/list', certifySharedPage, accessTokenParser, loginRequired, validator.retrieveRevisions, apiV3FormValidator, async(req, res) => {
     const pageId = req.query.pageId;
-    const limit = req.query.limit || await crowi.configManager.getConfig('crowi', 'customize:showPageLimitationS') || 10;
+    const limit = req.query.limit || await crowi.configManager.getConfig('customize:showPageLimitationS') || 10;
     const { isSharedPage } = req;
     const offset = req.query.offset || 0;
 

+ 120 - 120
apps/app/src/server/routes/apiv3/security-settings/index.js

@@ -349,52 +349,52 @@ module.exports = (crowi) => {
     const securityParams = {
       generalSetting: {
         restrictGuestMode: crowi.aclService.getGuestModeValue(),
-        pageDeletionAuthority: await configManager.getConfig('crowi', 'security:pageDeletionAuthority'),
-        pageCompleteDeletionAuthority: await configManager.getConfig('crowi', 'security:pageCompleteDeletionAuthority'),
-        pageRecursiveDeletionAuthority: await configManager.getConfig('crowi', 'security:pageRecursiveDeletionAuthority'),
-        pageRecursiveCompleteDeletionAuthority: await configManager.getConfig('crowi', 'security:pageRecursiveCompleteDeletionAuthority'),
+        pageDeletionAuthority: await configManager.getConfig('security:pageDeletionAuthority'),
+        pageCompleteDeletionAuthority: await configManager.getConfig('security:pageCompleteDeletionAuthority'),
+        pageRecursiveDeletionAuthority: await configManager.getConfig('security:pageRecursiveDeletionAuthority'),
+        pageRecursiveCompleteDeletionAuthority: await configManager.getConfig('security:pageRecursiveCompleteDeletionAuthority'),
         isAllGroupMembershipRequiredForPageCompleteDeletion:
-        await configManager.getConfig('crowi', 'security:isAllGroupMembershipRequiredForPageCompleteDeletion'),
-        hideRestrictedByOwner: await configManager.getConfig('crowi', 'security:list-policy:hideRestrictedByOwner'),
-        hideRestrictedByGroup: await configManager.getConfig('crowi', 'security:list-policy:hideRestrictedByGroup'),
-        isUsersHomepageDeletionEnabled: await configManager.getConfig('crowi', 'security:user-homepage-deletion:isEnabled'),
+        await configManager.getConfig('security:isAllGroupMembershipRequiredForPageCompleteDeletion'),
+        hideRestrictedByOwner: await configManager.getConfig('security:list-policy:hideRestrictedByOwner'),
+        hideRestrictedByGroup: await configManager.getConfig('security:list-policy:hideRestrictedByGroup'),
+        isUsersHomepageDeletionEnabled: await configManager.getConfig('security:user-homepage-deletion:isEnabled'),
         isForceDeleteUserHomepageOnUserDeletion:
-        await configManager.getConfig('crowi', 'security:user-homepage-deletion:isForceDeleteUserHomepageOnUserDeletion'),
-        isRomUserAllowedToComment: await configManager.getConfig('crowi', 'security:isRomUserAllowedToComment'),
-        wikiMode: await configManager.getConfig('crowi', 'security:wikiMode'),
-        sessionMaxAge: await configManager.getConfig('crowi', 'security:sessionMaxAge'),
+        await configManager.getConfig('security:user-homepage-deletion:isForceDeleteUserHomepageOnUserDeletion'),
+        isRomUserAllowedToComment: await configManager.getConfig('security:isRomUserAllowedToComment'),
+        wikiMode: await configManager.getConfig('security:wikiMode'),
+        sessionMaxAge: await configManager.getConfig('security:sessionMaxAge'),
       },
       shareLinkSetting: {
-        disableLinkSharing: await configManager.getConfig('crowi', 'security:disableLinkSharing'),
+        disableLinkSharing: await configManager.getConfig('security:disableLinkSharing'),
       },
       localSetting: {
-        useOnlyEnvVarsForSomeOptions: await configManager.getConfig('crowi', 'env:useOnlyEnvVars:security:passport-local'),
-        registrationMode: await configManager.getConfig('crowi', 'security:registrationMode'),
-        registrationWhitelist: await configManager.getConfig('crowi', 'security:registrationWhitelist'),
-        isPasswordResetEnabled: await configManager.getConfig('crowi', 'security:passport-local:isPasswordResetEnabled'),
-        isEmailAuthenticationEnabled: await configManager.getConfig('crowi', 'security:passport-local:isEmailAuthenticationEnabled'),
+        useOnlyEnvVarsForSomeOptions: await configManager.getConfig('env:useOnlyEnvVars:security:passport-local'),
+        registrationMode: await configManager.getConfig('security:registrationMode'),
+        registrationWhitelist: await configManager.getConfig('security:registrationWhitelist'),
+        isPasswordResetEnabled: await configManager.getConfig('security:passport-local:isPasswordResetEnabled'),
+        isEmailAuthenticationEnabled: await configManager.getConfig('security:passport-local:isEmailAuthenticationEnabled'),
       },
       generalAuth: {
-        isLocalEnabled: await configManager.getConfig('crowi', 'security:passport-local:isEnabled'),
-        isLdapEnabled: await configManager.getConfig('crowi', 'security:passport-ldap:isEnabled'),
-        isSamlEnabled: await configManager.getConfig('crowi', 'security:passport-saml:isEnabled'),
-        isOidcEnabled: await configManager.getConfig('crowi', 'security:passport-oidc:isEnabled'),
-        isGoogleEnabled: await configManager.getConfig('crowi', 'security:passport-google:isEnabled'),
-        isGitHubEnabled: await configManager.getConfig('crowi', 'security:passport-github:isEnabled'),
+        isLocalEnabled: await configManager.getConfig('security:passport-local:isEnabled'),
+        isLdapEnabled: await configManager.getConfig('security:passport-ldap:isEnabled'),
+        isSamlEnabled: await configManager.getConfig('security:passport-saml:isEnabled'),
+        isOidcEnabled: await configManager.getConfig('security:passport-oidc:isEnabled'),
+        isGoogleEnabled: await configManager.getConfig('security:passport-google:isEnabled'),
+        isGitHubEnabled: await configManager.getConfig('security:passport-github:isEnabled'),
       },
       ldapAuth: {
-        serverUrl: await configManager.getConfig('crowi', 'security:passport-ldap:serverUrl'),
-        isUserBind: await configManager.getConfig('crowi', 'security:passport-ldap:isUserBind'),
-        ldapBindDN: await configManager.getConfig('crowi', 'security:passport-ldap:bindDN'),
-        ldapBindDNPassword: await configManager.getConfig('crowi', 'security:passport-ldap:bindDNPassword'),
-        ldapSearchFilter: await configManager.getConfig('crowi', 'security:passport-ldap:searchFilter'),
-        ldapAttrMapUsername: await configManager.getConfig('crowi', 'security:passport-ldap:attrMapUsername'),
-        isSameUsernameTreatedAsIdenticalUser: await configManager.getConfig('crowi', 'security:passport-ldap:isSameUsernameTreatedAsIdenticalUser'),
-        ldapAttrMapMail: await configManager.getConfig('crowi', 'security:passport-ldap:attrMapMail'),
-        ldapAttrMapName: await configManager.getConfig('crowi', 'security:passport-ldap:attrMapName'),
-        ldapGroupSearchBase: await configManager.getConfig('crowi', 'security:passport-ldap:groupSearchBase'),
-        ldapGroupSearchFilter: await configManager.getConfig('crowi', 'security:passport-ldap:groupSearchFilter'),
-        ldapGroupDnProperty: await configManager.getConfig('crowi', 'security:passport-ldap:groupDnProperty'),
+        serverUrl: await configManager.getConfig('security:passport-ldap:serverUrl'),
+        isUserBind: await configManager.getConfig('security:passport-ldap:isUserBind'),
+        ldapBindDN: await configManager.getConfig('security:passport-ldap:bindDN'),
+        ldapBindDNPassword: await configManager.getConfig('security:passport-ldap:bindDNPassword'),
+        ldapSearchFilter: await configManager.getConfig('security:passport-ldap:searchFilter'),
+        ldapAttrMapUsername: await configManager.getConfig('security:passport-ldap:attrMapUsername'),
+        isSameUsernameTreatedAsIdenticalUser: await configManager.getConfig('security:passport-ldap:isSameUsernameTreatedAsIdenticalUser'),
+        ldapAttrMapMail: await configManager.getConfig('security:passport-ldap:attrMapMail'),
+        ldapAttrMapName: await configManager.getConfig('security:passport-ldap:attrMapName'),
+        ldapGroupSearchBase: await configManager.getConfig('security:passport-ldap:groupSearchBase'),
+        ldapGroupSearchFilter: await configManager.getConfig('security:passport-ldap:groupSearchFilter'),
+        ldapGroupDnProperty: await configManager.getConfig('security:passport-ldap:groupDnProperty'),
       },
       samlAuth: {
         missingMandatoryConfigKeys: await crowi.passportService.getSamlMissingMandatoryConfigKeys(),
@@ -415,40 +415,40 @@ module.exports = (crowi) => {
         samlEnvVarAttrMapFirstName: await configManager.getConfig('security:passport-saml:attrMapFirstName', ConfigSource.env),
         samlAttrMapLastName: await configManager.getConfig('security:passport-saml:attrMapLastName', ConfigSource.db),
         samlEnvVarAttrMapLastName: await configManager.getConfig('security:passport-saml:attrMapLastName', ConfigSource.env),
-        isSameUsernameTreatedAsIdenticalUser: await configManager.getConfig('crowi', 'security:passport-saml:isSameUsernameTreatedAsIdenticalUser'),
-        isSameEmailTreatedAsIdenticalUser: await configManager.getConfig('crowi', 'security:passport-saml:isSameEmailTreatedAsIdenticalUser'),
+        isSameUsernameTreatedAsIdenticalUser: await configManager.getConfig('security:passport-saml:isSameUsernameTreatedAsIdenticalUser'),
+        isSameEmailTreatedAsIdenticalUser: await configManager.getConfig('security:passport-saml:isSameEmailTreatedAsIdenticalUser'),
         samlABLCRule: await configManager.getConfig('security:passport-saml:ABLCRule', ConfigSource.db),
         samlEnvVarABLCRule: await configManager.getConfig('security:passport-saml:ABLCRule', ConfigSource.env),
       },
       oidcAuth: {
-        oidcProviderName: await configManager.getConfig('crowi', 'security:passport-oidc:providerName'),
-        oidcIssuerHost: await configManager.getConfig('crowi', 'security:passport-oidc:issuerHost'),
-        oidcAuthorizationEndpoint: await configManager.getConfig('crowi', 'security:passport-oidc:authorizationEndpoint'),
-        oidcTokenEndpoint: await configManager.getConfig('crowi', 'security:passport-oidc:tokenEndpoint'),
-        oidcRevocationEndpoint: await configManager.getConfig('crowi', 'security:passport-oidc:revocationEndpoint'),
-        oidcIntrospectionEndpoint: await configManager.getConfig('crowi', 'security:passport-oidc:introspectionEndpoint'),
-        oidcUserInfoEndpoint: await configManager.getConfig('crowi', 'security:passport-oidc:userInfoEndpoint'),
-        oidcEndSessionEndpoint: await configManager.getConfig('crowi', 'security:passport-oidc:endSessionEndpoint'),
-        oidcRegistrationEndpoint: await configManager.getConfig('crowi', 'security:passport-oidc:registrationEndpoint'),
-        oidcJWKSUri: await configManager.getConfig('crowi', 'security:passport-oidc:jwksUri'),
-        oidcClientId: await configManager.getConfig('crowi', 'security:passport-oidc:clientId'),
-        oidcClientSecret: await configManager.getConfig('crowi', 'security:passport-oidc:clientSecret'),
-        oidcAttrMapId: await configManager.getConfig('crowi', 'security:passport-oidc:attrMapId'),
-        oidcAttrMapUserName: await configManager.getConfig('crowi', 'security:passport-oidc:attrMapUserName'),
-        oidcAttrMapName: await configManager.getConfig('crowi', 'security:passport-oidc:attrMapName'),
-        oidcAttrMapEmail: await configManager.getConfig('crowi', 'security:passport-oidc:attrMapMail'),
-        isSameUsernameTreatedAsIdenticalUser: await configManager.getConfig('crowi', 'security:passport-oidc:isSameUsernameTreatedAsIdenticalUser'),
-        isSameEmailTreatedAsIdenticalUser: await configManager.getConfig('crowi', 'security:passport-oidc:isSameEmailTreatedAsIdenticalUser'),
+        oidcProviderName: await configManager.getConfig('security:passport-oidc:providerName'),
+        oidcIssuerHost: await configManager.getConfig('security:passport-oidc:issuerHost'),
+        oidcAuthorizationEndpoint: await configManager.getConfig('security:passport-oidc:authorizationEndpoint'),
+        oidcTokenEndpoint: await configManager.getConfig('security:passport-oidc:tokenEndpoint'),
+        oidcRevocationEndpoint: await configManager.getConfig('security:passport-oidc:revocationEndpoint'),
+        oidcIntrospectionEndpoint: await configManager.getConfig('security:passport-oidc:introspectionEndpoint'),
+        oidcUserInfoEndpoint: await configManager.getConfig('security:passport-oidc:userInfoEndpoint'),
+        oidcEndSessionEndpoint: await configManager.getConfig('security:passport-oidc:endSessionEndpoint'),
+        oidcRegistrationEndpoint: await configManager.getConfig('security:passport-oidc:registrationEndpoint'),
+        oidcJWKSUri: await configManager.getConfig('security:passport-oidc:jwksUri'),
+        oidcClientId: await configManager.getConfig('security:passport-oidc:clientId'),
+        oidcClientSecret: await configManager.getConfig('security:passport-oidc:clientSecret'),
+        oidcAttrMapId: await configManager.getConfig('security:passport-oidc:attrMapId'),
+        oidcAttrMapUserName: await configManager.getConfig('security:passport-oidc:attrMapUserName'),
+        oidcAttrMapName: await configManager.getConfig('security:passport-oidc:attrMapName'),
+        oidcAttrMapEmail: await configManager.getConfig('security:passport-oidc:attrMapMail'),
+        isSameUsernameTreatedAsIdenticalUser: await configManager.getConfig('security:passport-oidc:isSameUsernameTreatedAsIdenticalUser'),
+        isSameEmailTreatedAsIdenticalUser: await configManager.getConfig('security:passport-oidc:isSameEmailTreatedAsIdenticalUser'),
       },
       googleOAuth: {
-        googleClientId: await configManager.getConfig('crowi', 'security:passport-google:clientId'),
-        googleClientSecret: await configManager.getConfig('crowi', 'security:passport-google:clientSecret'),
-        isSameEmailTreatedAsIdenticalUser: await configManager.getConfig('crowi', 'security:passport-google:isSameEmailTreatedAsIdenticalUser'),
+        googleClientId: await configManager.getConfig('security:passport-google:clientId'),
+        googleClientSecret: await configManager.getConfig('security:passport-google:clientSecret'),
+        isSameEmailTreatedAsIdenticalUser: await configManager.getConfig('security:passport-google:isSameEmailTreatedAsIdenticalUser'),
       },
       githubOAuth: {
-        githubClientId: await configManager.getConfig('crowi', 'security:passport-github:clientId'),
-        githubClientSecret: await configManager.getConfig('crowi', 'security:passport-github:clientSecret'),
-        isSameUsernameTreatedAsIdenticalUser: await configManager.getConfig('crowi', 'security:passport-github:isSameUsernameTreatedAsIdenticalUser'),
+        githubClientId: await configManager.getConfig('security:passport-github:clientId'),
+        githubClientSecret: await configManager.getConfig('security:passport-github:clientSecret'),
+        isSameUsernameTreatedAsIdenticalUser: await configManager.getConfig('security:passport-github:isSameUsernameTreatedAsIdenticalUser'),
       },
     };
     return res.apiv3({ securityParams });
@@ -511,7 +511,7 @@ module.exports = (crowi) => {
       await updateAndReloadStrategySettings(authId, enableParams);
 
       const responseParams = {
-        [`security:passport-${authId}:isEnabled`]: await configManager.getConfig('crowi', `security:passport-${authId}:isEnabled`),
+        [`security:passport-${authId}:isEnabled`]: await configManager.getConfig(`security:passport-${authId}:isEnabled`),
       };
       switch (authId) {
         case 'local':
@@ -647,7 +647,7 @@ module.exports = (crowi) => {
       return res.apiv3Err(new ErrorV3('Delete config values are not correct.', 'delete_config_not_normalized'));
     }
 
-    const wikiMode = await configManager.getConfig('crowi', 'security:wikiMode');
+    const wikiMode = await configManager.getConfig('security:wikiMode');
     if (wikiMode === 'private' || wikiMode === 'public') {
       logger.debug('security:restrictGuestMode will not be changed because wiki mode is forced to set');
       delete updateData['security:restrictGuestMode'];
@@ -655,20 +655,20 @@ module.exports = (crowi) => {
     try {
       await configManager.updateConfigs(updateData);
       const securitySettingParams = {
-        sessionMaxAge: await configManager.getConfig('crowi', 'security:sessionMaxAge'),
-        restrictGuestMode: await configManager.getConfig('crowi', 'security:restrictGuestMode'),
-        pageDeletionAuthority: await configManager.getConfig('crowi', 'security:pageDeletionAuthority'),
-        pageCompleteDeletionAuthority: await configManager.getConfig('crowi', 'security:pageCompleteDeletionAuthority'),
-        pageRecursiveDeletionAuthority: await configManager.getConfig('crowi', 'security:pageRecursiveDeletionAuthority'),
-        pageRecursiveCompleteDeletionAuthority: await configManager.getConfig('crowi', 'security:pageRecursiveCompleteDeletionAuthority'),
+        sessionMaxAge: await configManager.getConfig('security:sessionMaxAge'),
+        restrictGuestMode: await configManager.getConfig('security:restrictGuestMode'),
+        pageDeletionAuthority: await configManager.getConfig('security:pageDeletionAuthority'),
+        pageCompleteDeletionAuthority: await configManager.getConfig('security:pageCompleteDeletionAuthority'),
+        pageRecursiveDeletionAuthority: await configManager.getConfig('security:pageRecursiveDeletionAuthority'),
+        pageRecursiveCompleteDeletionAuthority: await configManager.getConfig('security:pageRecursiveCompleteDeletionAuthority'),
         isAllGroupMembershipRequiredForPageCompleteDeletion:
-        await configManager.getConfig('crowi', 'security:isAllGroupMembershipRequiredForPageCompleteDeletion'),
-        hideRestrictedByOwner: await configManager.getConfig('crowi', 'security:list-policy:hideRestrictedByOwner'),
-        hideRestrictedByGroup: await configManager.getConfig('crowi', 'security:list-policy:hideRestrictedByGroup'),
-        isUsersHomepageDeletionEnabled: await configManager.getConfig('crowi', 'security:user-homepage-deletion:isEnabled'),
+        await configManager.getConfig('security:isAllGroupMembershipRequiredForPageCompleteDeletion'),
+        hideRestrictedByOwner: await configManager.getConfig('security:list-policy:hideRestrictedByOwner'),
+        hideRestrictedByGroup: await configManager.getConfig('security:list-policy:hideRestrictedByGroup'),
+        isUsersHomepageDeletionEnabled: await configManager.getConfig('security:user-homepage-deletion:isEnabled'),
         isForceDeleteUserHomepageOnUserDeletion:
-        await configManager.getConfig('crowi', 'security:user-homepage-deletion:isForceDeleteUserHomepageOnUserDeletion'),
-        isRomUserAllowedToComment: await configManager.getConfig('crowi', 'security:isRomUserAllowedToComment'),
+        await configManager.getConfig('security:user-homepage-deletion:isForceDeleteUserHomepageOnUserDeletion'),
+        isRomUserAllowedToComment: await configManager.getConfig('security:isRomUserAllowedToComment'),
       };
 
       const parameters = { action: SupportedAction.ACTION_ADMIN_SECURITY_SETTINGS_UPDATE };
@@ -711,7 +711,7 @@ module.exports = (crowi) => {
     try {
       await configManager.updateConfigs(updateData);
       const securitySettingParams = {
-        disableLinkSharing: configManager.getConfig('crowi', 'security:disableLinkSharing'),
+        disableLinkSharing: configManager.getConfig('security:disableLinkSharing'),
       };
       // eslint-disable-next-line max-len
       const parameters = { action: updateData['security:disableLinkSharing'] ? SupportedAction.ACTION_ADMIN_REJECT_SHARE_LINK : SupportedAction.ACTION_ADMIN_PERMIT_SHARE_LINK };
@@ -830,10 +830,10 @@ module.exports = (crowi) => {
       await updateAndReloadStrategySettings('local', requestParams);
 
       const localSettingParams = {
-        registrationMode: await configManager.getConfig('crowi', 'security:registrationMode'),
-        registrationWhitelist: await configManager.getConfig('crowi', 'security:registrationWhitelist'),
-        isPasswordResetEnabled: await configManager.getConfig('crowi', 'security:passport-local:isPasswordResetEnabled'),
-        isEmailAuthenticationEnabled: await configManager.getConfig('crowi', 'security:passport-local:isEmailAuthenticationEnabled'),
+        registrationMode: await configManager.getConfig('security:registrationMode'),
+        registrationWhitelist: await configManager.getConfig('security:registrationWhitelist'),
+        isPasswordResetEnabled: await configManager.getConfig('security:passport-local:isPasswordResetEnabled'),
+        isEmailAuthenticationEnabled: await configManager.getConfig('security:passport-local:isEmailAuthenticationEnabled'),
       };
       const parameters = { action: SupportedAction.ACTION_ADMIN_AUTH_ID_PASS_UPDATE };
       activityEvent.emit('update', res.locals.activity._id, parameters);
@@ -887,18 +887,18 @@ module.exports = (crowi) => {
       await updateAndReloadStrategySettings('ldap', requestParams);
 
       const securitySettingParams = {
-        serverUrl: await configManager.getConfig('crowi', 'security:passport-ldap:serverUrl'),
-        isUserBind: await configManager.getConfig('crowi', 'security:passport-ldap:isUserBind'),
-        ldapBindDN: await configManager.getConfig('crowi', 'security:passport-ldap:bindDN'),
-        ldapBindDNPassword: await configManager.getConfig('crowi', 'security:passport-ldap:bindDNPassword'),
-        ldapSearchFilter: await configManager.getConfig('crowi', 'security:passport-ldap:searchFilter'),
-        ldapAttrMapUsername: await configManager.getConfig('crowi', 'security:passport-ldap:attrMapUsername'),
-        isSameUsernameTreatedAsIdenticalUser: await configManager.getConfig('crowi', 'security:passport-ldap:isSameUsernameTreatedAsIdenticalUser'),
-        ldapAttrMapMail: await configManager.getConfig('crowi', 'security:passport-ldap:attrMapMail'),
-        ldapAttrMapName: await configManager.getConfig('crowi', 'security:passport-ldap:attrMapName'),
-        ldapGroupSearchBase: await configManager.getConfig('crowi', 'security:passport-ldap:groupSearchBase'),
-        ldapGroupSearchFilter: await configManager.getConfig('crowi', 'security:passport-ldap:groupSearchFilter'),
-        ldapGroupDnProperty: await configManager.getConfig('crowi', 'security:passport-ldap:groupDnProperty'),
+        serverUrl: await configManager.getConfig('security:passport-ldap:serverUrl'),
+        isUserBind: await configManager.getConfig('security:passport-ldap:isUserBind'),
+        ldapBindDN: await configManager.getConfig('security:passport-ldap:bindDN'),
+        ldapBindDNPassword: await configManager.getConfig('security:passport-ldap:bindDNPassword'),
+        ldapSearchFilter: await configManager.getConfig('security:passport-ldap:searchFilter'),
+        ldapAttrMapUsername: await configManager.getConfig('security:passport-ldap:attrMapUsername'),
+        isSameUsernameTreatedAsIdenticalUser: await configManager.getConfig('security:passport-ldap:isSameUsernameTreatedAsIdenticalUser'),
+        ldapAttrMapMail: await configManager.getConfig('security:passport-ldap:attrMapMail'),
+        ldapAttrMapName: await configManager.getConfig('security:passport-ldap:attrMapName'),
+        ldapGroupSearchBase: await configManager.getConfig('security:passport-ldap:groupSearchBase'),
+        ldapGroupSearchFilter: await configManager.getConfig('security:passport-ldap:groupSearchFilter'),
+        ldapGroupDnProperty: await configManager.getConfig('security:passport-ldap:groupDnProperty'),
       };
       const parameters = { action: SupportedAction.ACTION_ADMIN_AUTH_LDAP_UPDATE };
       activityEvent.emit('update', res.locals.activity._id, parameters);
@@ -990,9 +990,9 @@ module.exports = (crowi) => {
         samlAttrMapMail: await configManager.getConfig('security:passport-saml:attrMapMail', ConfigSource.db),
         samlAttrMapFirstName: await configManager.getConfig('security:passport-saml:attrMapFirstName', ConfigSource.db),
         samlAttrMapLastName: await configManager.getConfig('security:passport-saml:attrMapLastName', ConfigSource.db),
-        isSameUsernameTreatedAsIdenticalUser: await configManager.getConfig('crowi', 'security:passport-saml:isSameUsernameTreatedAsIdenticalUser'),
-        isSameEmailTreatedAsIdenticalUser: await configManager.getConfig('crowi', 'security:passport-saml:isSameEmailTreatedAsIdenticalUser'),
-        samlABLCRule: await configManager.getConfig('crowi', 'security:passport-saml:ABLCRule'),
+        isSameUsernameTreatedAsIdenticalUser: await configManager.getConfig('security:passport-saml:isSameUsernameTreatedAsIdenticalUser'),
+        isSameEmailTreatedAsIdenticalUser: await configManager.getConfig('security:passport-saml:isSameEmailTreatedAsIdenticalUser'),
+        samlABLCRule: await configManager.getConfig('security:passport-saml:ABLCRule'),
       };
       const parameters = { action: SupportedAction.ACTION_ADMIN_AUTH_SAML_UPDATE };
       activityEvent.emit('update', res.locals.activity._id, parameters);
@@ -1052,24 +1052,24 @@ module.exports = (crowi) => {
       await updateAndReloadStrategySettings('oidc', requestParams);
 
       const securitySettingParams = {
-        oidcProviderName: await configManager.getConfig('crowi', 'security:passport-oidc:providerName'),
-        oidcIssuerHost: await configManager.getConfig('crowi', 'security:passport-oidc:issuerHost'),
-        oidcAuthorizationEndpoint: await configManager.getConfig('crowi', 'security:passport-oidc:authorizationEndpoint'),
-        oidcTokenEndpoint: await configManager.getConfig('crowi', 'security:passport-oidc:tokenEndpoint'),
-        oidcRevocationEndpoint: await configManager.getConfig('crowi', 'security:passport-oidc:revocationEndpoint'),
-        oidcIntrospectionEndpoint: await configManager.getConfig('crowi', 'security:passport-oidc:introspectionEndpoint'),
-        oidcUserInfoEndpoint: await configManager.getConfig('crowi', 'security:passport-oidc:userInfoEndpoint'),
-        oidcEndSessionEndpoint: await configManager.getConfig('crowi', 'security:passport-oidc:endSessionEndpoint'),
-        oidcRegistrationEndpoint: await configManager.getConfig('crowi', 'security:passport-oidc:registrationEndpoint'),
-        oidcJWKSUri: await configManager.getConfig('crowi', 'security:passport-oidc:jwksUri'),
-        oidcClientId: await configManager.getConfig('crowi', 'security:passport-oidc:clientId'),
-        oidcClientSecret: await configManager.getConfig('crowi', 'security:passport-oidc:clientSecret'),
-        oidcAttrMapId: await configManager.getConfig('crowi', 'security:passport-oidc:attrMapId'),
-        oidcAttrMapUserName: await configManager.getConfig('crowi', 'security:passport-oidc:attrMapUserName'),
-        oidcAttrMapName: await configManager.getConfig('crowi', 'security:passport-oidc:attrMapName'),
-        oidcAttrMapEmail: await configManager.getConfig('crowi', 'security:passport-oidc:attrMapMail'),
-        isSameUsernameTreatedAsIdenticalUser: await configManager.getConfig('crowi', 'security:passport-oidc:isSameUsernameTreatedAsIdenticalUser'),
-        isSameEmailTreatedAsIdenticalUser: await configManager.getConfig('crowi', 'security:passport-oidc:isSameEmailTreatedAsIdenticalUser'),
+        oidcProviderName: await configManager.getConfig('security:passport-oidc:providerName'),
+        oidcIssuerHost: await configManager.getConfig('security:passport-oidc:issuerHost'),
+        oidcAuthorizationEndpoint: await configManager.getConfig('security:passport-oidc:authorizationEndpoint'),
+        oidcTokenEndpoint: await configManager.getConfig('security:passport-oidc:tokenEndpoint'),
+        oidcRevocationEndpoint: await configManager.getConfig('security:passport-oidc:revocationEndpoint'),
+        oidcIntrospectionEndpoint: await configManager.getConfig('security:passport-oidc:introspectionEndpoint'),
+        oidcUserInfoEndpoint: await configManager.getConfig('security:passport-oidc:userInfoEndpoint'),
+        oidcEndSessionEndpoint: await configManager.getConfig('security:passport-oidc:endSessionEndpoint'),
+        oidcRegistrationEndpoint: await configManager.getConfig('security:passport-oidc:registrationEndpoint'),
+        oidcJWKSUri: await configManager.getConfig('security:passport-oidc:jwksUri'),
+        oidcClientId: await configManager.getConfig('security:passport-oidc:clientId'),
+        oidcClientSecret: await configManager.getConfig('security:passport-oidc:clientSecret'),
+        oidcAttrMapId: await configManager.getConfig('security:passport-oidc:attrMapId'),
+        oidcAttrMapUserName: await configManager.getConfig('security:passport-oidc:attrMapUserName'),
+        oidcAttrMapName: await configManager.getConfig('security:passport-oidc:attrMapName'),
+        oidcAttrMapEmail: await configManager.getConfig('security:passport-oidc:attrMapMail'),
+        isSameUsernameTreatedAsIdenticalUser: await configManager.getConfig('security:passport-oidc:isSameUsernameTreatedAsIdenticalUser'),
+        isSameEmailTreatedAsIdenticalUser: await configManager.getConfig('security:passport-oidc:isSameEmailTreatedAsIdenticalUser'),
       };
       const parameters = { action: SupportedAction.ACTION_ADMIN_AUTH_OIDC_UPDATE };
       activityEvent.emit('update', res.locals.activity._id, parameters);
@@ -1115,9 +1115,9 @@ module.exports = (crowi) => {
       await updateAndReloadStrategySettings('google', requestParams);
 
       const securitySettingParams = {
-        googleClientId: await configManager.getConfig('crowi', 'security:passport-google:clientId'),
-        googleClientSecret: await configManager.getConfig('crowi', 'security:passport-google:clientSecret'),
-        isSameEmailTreatedAsIdenticalUser: await configManager.getConfig('crowi', 'security:passport-google:isSameEmailTreatedAsIdenticalUser'),
+        googleClientId: await configManager.getConfig('security:passport-google:clientId'),
+        googleClientSecret: await configManager.getConfig('security:passport-google:clientSecret'),
+        isSameEmailTreatedAsIdenticalUser: await configManager.getConfig('security:passport-google:isSameEmailTreatedAsIdenticalUser'),
       };
       const parameters = { action: SupportedAction.ACTION_ADMIN_AUTH_GOOGLE_UPDATE };
       activityEvent.emit('update', res.locals.activity._id, parameters);
@@ -1162,9 +1162,9 @@ module.exports = (crowi) => {
       await updateAndReloadStrategySettings('github', requestParams);
 
       const securitySettingParams = {
-        githubClientId: await configManager.getConfig('crowi', 'security:passport-github:clientId'),
-        githubClientSecret: await configManager.getConfig('crowi', 'security:passport-github:clientSecret'),
-        isSameUsernameTreatedAsIdenticalUser: await configManager.getConfig('crowi', 'security:passport-github:isSameUsernameTreatedAsIdenticalUser'),
+        githubClientId: await configManager.getConfig('security:passport-github:clientId'),
+        githubClientSecret: await configManager.getConfig('security:passport-github:clientSecret'),
+        isSameUsernameTreatedAsIdenticalUser: await configManager.getConfig('security:passport-github:isSameUsernameTreatedAsIdenticalUser'),
       };
       const parameters = { action: SupportedAction.ACTION_ADMIN_AUTH_GITHUB_UPDATE };
       activityEvent.emit('update', res.locals.activity._id, parameters);

+ 1 - 1
apps/app/src/server/routes/apiv3/share-links.js

@@ -33,7 +33,7 @@ module.exports = (crowi) => {
    * middleware to limit link sharing
    */
   const linkSharingRequired = (req, res, next) => {
-    const isLinkSharingDisabled = crowi.configManager.getConfig('crowi', 'security:disableLinkSharing');
+    const isLinkSharingDisabled = crowi.configManager.getConfig('security:disableLinkSharing');
     logger.debug(`isLinkSharingDisabled: ${isLinkSharingDisabled}`);
 
     if (isLinkSharingDisabled) {

+ 6 - 6
apps/app/src/server/routes/apiv3/slack-integration-legacy-settings.js

@@ -70,9 +70,9 @@ module.exports = (crowi) => {
 
     const slackIntegrationParams = {
       isSlackbotConfigured: crowi.slackIntegrationService.isSlackbotConfigured,
-      webhookUrl: await crowi.configManager.getConfig('notification', 'slack:incomingWebhookUrl'),
-      isIncomingWebhookPrioritized: await crowi.configManager.getConfig('notification', 'slack:isIncomingWebhookPrioritized'),
-      slackToken: await crowi.configManager.getConfig('notification', 'slack:token'),
+      webhookUrl: await crowi.configManager.getConfig('slack:incomingWebhookUrl'),
+      isIncomingWebhookPrioritized: await crowi.configManager.getConfig('slack:isIncomingWebhookPrioritized'),
+      slackToken: await crowi.configManager.getConfig('slack:token'),
     };
     return res.apiv3({ slackIntegrationParams });
   });
@@ -109,9 +109,9 @@ module.exports = (crowi) => {
     try {
       await configManager.updateConfigs(requestParams);
       const responseParams = {
-        webhookUrl: await crowi.configManager.getConfig('notification', 'slack:incomingWebhookUrl'),
-        isIncomingWebhookPrioritized: await crowi.configManager.getConfig('notification', 'slack:isIncomingWebhookPrioritized'),
-        slackToken: await crowi.configManager.getConfig('notification', 'slack:token'),
+        webhookUrl: await crowi.configManager.getConfig('slack:incomingWebhookUrl'),
+        isIncomingWebhookPrioritized: await crowi.configManager.getConfig('slack:isIncomingWebhookPrioritized'),
+        slackToken: await crowi.configManager.getConfig('slack:token'),
       };
 
       const parameters = { action: SupportedAction.ACTION_ADMIN_SLACK_CONFIGURATION_SETTING_UPDATE };

+ 13 - 13
apps/app/src/server/routes/apiv3/slack-integration-settings.js

@@ -172,17 +172,17 @@ module.exports = (crowi) => {
   router.get('/', accessTokenParser, loginRequiredStrictly, adminRequired, async(req, res) => {
 
     const { configManager, slackIntegrationService } = crowi;
-    const currentBotType = configManager.getConfig('crowi', 'slackbot:currentBotType');
+    const currentBotType = configManager.getConfig('slackbot:currentBotType');
 
     // retrieve settings
     const settings = {};
     if (currentBotType === SlackbotType.CUSTOM_WITHOUT_PROXY) {
       settings.slackSigningSecretEnvVars = configManager.getConfig('slackbot:withoutProxy:signingSecret', ConfigSource.env);
       settings.slackBotTokenEnvVars = configManager.getConfig('slackbot:withoutProxy:botToken', ConfigSource.env);
-      settings.slackSigningSecret = configManager.getConfig('crowi', 'slackbot:withoutProxy:signingSecret');
-      settings.slackBotToken = configManager.getConfig('crowi', 'slackbot:withoutProxy:botToken');
-      settings.commandPermission = configManager.getConfig('crowi', 'slackbot:withoutProxy:commandPermission');
-      settings.eventActionsPermission = configManager.getConfig('crowi', 'slackbot:withoutProxy:eventActionsPermission');
+      settings.slackSigningSecret = configManager.getConfig('slackbot:withoutProxy:signingSecret');
+      settings.slackBotToken = configManager.getConfig('slackbot:withoutProxy:botToken');
+      settings.commandPermission = configManager.getConfig('slackbot:withoutProxy:commandPermission');
+      settings.eventActionsPermission = configManager.getConfig('slackbot:withoutProxy:eventActionsPermission');
     }
     else {
       settings.proxyServerUri = slackIntegrationService.proxyUriForCurrentType;
@@ -281,7 +281,7 @@ module.exports = (crowi) => {
     }
 
     // TODO Impl to delete AccessToken both of Proxy and GROWI when botType changes.
-    const slackBotTypeParam = { slackBotType: crowi.configManager.getConfig('crowi', 'slackbot:currentBotType') };
+    const slackBotTypeParam = { slackBotType: crowi.configManager.getConfig('slackbot:currentBotType') };
     return res.apiv3({ slackBotTypeParam });
   };
 
@@ -369,7 +369,7 @@ module.exports = (crowi) => {
    *             description: Succeeded to put CustomBotWithoutProxy setting.
    */
   router.put('/without-proxy/update-settings', loginRequiredStrictly, adminRequired, addActivity, async(req, res) => {
-    const currentBotType = crowi.configManager.getConfig('crowi', 'slackbot:currentBotType');
+    const currentBotType = crowi.configManager.getConfig('slackbot:currentBotType');
     if (currentBotType !== SlackbotType.CUSTOM_WITHOUT_PROXY) {
       const msg = 'Not CustomBotWithoutProxy';
       return res.apiv3Err(new ErrorV3(msg, 'not-customBotWithoutProxy'), 400);
@@ -410,7 +410,7 @@ module.exports = (crowi) => {
    */
   // eslint-disable-next-line max-len
   router.put('/without-proxy/update-permissions', loginRequiredStrictly, adminRequired, addActivity, validator.updatePermissionsWithoutProxy, async(req, res) => {
-    const currentBotType = crowi.configManager.getConfig('crowi', 'slackbot:currentBotType');
+    const currentBotType = crowi.configManager.getConfig('slackbot:currentBotType');
     if (currentBotType !== SlackbotType.CUSTOM_WITHOUT_PROXY) {
       const msg = 'Not CustomBotWithoutProxy';
       return res.apiv3Err(new ErrorV3(msg, 'not-customBotWithoutProxy'), 400);
@@ -700,7 +700,7 @@ module.exports = (crowi) => {
    */
   // eslint-disable-next-line max-len
   router.post('/slack-app-integrations/:id/relation-test', loginRequiredStrictly, adminRequired, addActivity, validator.relationTest, apiV3FormValidator, async(req, res) => {
-    const currentBotType = crowi.configManager.getConfig('crowi', 'slackbot:currentBotType');
+    const currentBotType = crowi.configManager.getConfig('slackbot:currentBotType');
     if (currentBotType === SlackbotType.CUSTOM_WITHOUT_PROXY) {
       const msg = 'Not Proxy Type';
       return res.apiv3Err(new ErrorV3(msg, 'not-proxy-type'), 400);
@@ -742,7 +742,7 @@ module.exports = (crowi) => {
     }
 
     const { channel } = req.body;
-    const appSiteURL = crowi.configManager.getConfig('crowi', 'app:siteUrl');
+    const appSiteURL = crowi.configManager.getConfig('app:siteUrl');
     try {
       await sendSuccessMessage(slackBotToken, channel, appSiteURL);
     }
@@ -777,20 +777,20 @@ module.exports = (crowi) => {
    *             description: Succeeded to connect to slack work space.
    */
   router.post('/without-proxy/test', loginRequiredStrictly, adminRequired, addActivity, validator.slackChannel, apiV3FormValidator, async(req, res) => {
-    const currentBotType = crowi.configManager.getConfig('crowi', 'slackbot:currentBotType');
+    const currentBotType = crowi.configManager.getConfig('slackbot:currentBotType');
     if (currentBotType !== SlackbotType.CUSTOM_WITHOUT_PROXY) {
       const msg = 'Select Without Proxy Type';
       return res.apiv3Err(new ErrorV3(msg, 'select-not-proxy-type'), 400);
     }
 
-    const slackBotToken = crowi.configManager.getConfig('crowi', 'slackbot:withoutProxy:botToken');
+    const slackBotToken = crowi.configManager.getConfig('slackbot:withoutProxy:botToken');
     const status = await getConnectionStatus(slackBotToken);
     if (status.error != null) {
       return res.apiv3Err(new ErrorV3(`Error occured while getting connection. ${status.error}`, 'send-message-failed'));
     }
 
     const { channel } = req.body;
-    const appSiteURL = crowi.configManager.getConfig('crowi', 'app:siteUrl');
+    const appSiteURL = crowi.configManager.getConfig('app:siteUrl');
     try {
       await sendSuccessMessage(slackBotToken, channel, appSiteURL);
     }

+ 4 - 4
apps/app/src/server/routes/apiv3/slack-integration.js

@@ -117,7 +117,7 @@ module.exports = (crowi) => {
     }
 
     // without proxy
-    commandPermission = configManager.getConfig('crowi', 'slackbot:withoutProxy:commandPermission');
+    commandPermission = configManager.getConfig('slackbot:withoutProxy:commandPermission');
 
     const isPermitted = checkPermission(commandPermission, growiCommand.growiCommandType, fromChannel);
     if (isPermitted) {
@@ -164,7 +164,7 @@ module.exports = (crowi) => {
     }
 
     // without proxy
-    commandPermission = configManager.getConfig('crowi', 'slackbot:withoutProxy:commandPermission');
+    commandPermission = configManager.getConfig('slackbot:withoutProxy:commandPermission');
 
     const isPermitted = checkPermission(commandPermission, callbacIdkOrActionId, fromChannel);
     if (isPermitted) {
@@ -184,7 +184,7 @@ module.exports = (crowi) => {
   }
 
   const addSigningSecretToReq = (req, res, next) => {
-    req.slackSigningSecret = configManager.getConfig('crowi', 'slackbot:withoutProxy:signingSecret');
+    req.slackSigningSecret = configManager.getConfig('slackbot:withoutProxy:signingSecret');
     return next();
   };
 
@@ -399,7 +399,7 @@ module.exports = (crowi) => {
     try {
       const client = await slackIntegrationService.generateClientForCustomBotWithoutProxy();
       // convert permission object to map
-      const permission = new Map(Object.entries(crowi.configManager.getConfig('crowi', 'slackbot:withoutProxy:eventActionsPermission')));
+      const permission = new Map(Object.entries(crowi.configManager.getConfig('slackbot:withoutProxy:eventActionsPermission')));
 
       await crowi.slackIntegrationService.handleEventsRequest(client, growiBotEvent, permission);
 

+ 1 - 1
apps/app/src/server/routes/apiv3/staffs.js

@@ -25,7 +25,7 @@ module.exports = (crowi) => {
 
   router.get('/', async(req, res) => {
     const now = new Date();
-    const growiCloudUri = await crowi.configManager.getConfig('crowi', 'app:growiCloudUri');
+    const growiCloudUri = await crowi.configManager.getConfig('app:growiCloudUri');
 
     if (growiCloudUri != null && (expiredAt == null || isAfter(now, expiredAt))) {
       const url = new URL('_api/staffCredit', growiCloudUri);

+ 6 - 6
apps/app/src/server/routes/apiv3/user-activation.ts

@@ -83,12 +83,12 @@ export const completeRegistrationAction = (crowi) => {
     }
 
     // error when registration is not allowed
-    if (configManager.getConfig('crowi', 'security:registrationMode') === aclService.labels.SECURITY_REGISTRATION_MODE_CLOSED) {
+    if (configManager.getConfig('security:registrationMode') === aclService.labels.SECURITY_REGISTRATION_MODE_CLOSED) {
       return res.apiv3Err(new ErrorV3('Registration closed', 'registration-failed'), 403);
     }
 
     // error when email authentication is disabled
-    if (configManager.getConfig('crowi', 'security:passport-local:isEmailAuthenticationEnabled') !== true) {
+    if (configManager.getConfig('security:passport-local:isEmailAuthenticationEnabled') !== true) {
       return res.apiv3Err(new ErrorV3('Email authentication configuration is disabled', 'registration-failed'), 403);
     }
 
@@ -138,13 +138,13 @@ export const completeRegistrationAction = (crowi) => {
 
         userRegistrationOrder.revokeOneTimeToken();
 
-        if (configManager.getConfig('crowi', 'security:registrationMode') === aclService.labels.SECURITY_REGISTRATION_MODE_RESTRICTED) {
+        if (configManager.getConfig('security:registrationMode') === aclService.labels.SECURITY_REGISTRATION_MODE_RESTRICTED) {
           const isMailerSetup = mailService.isMailerSetup ?? false;
 
           if (isMailerSetup) {
             const admins = await User.findAdmins();
             const appTitle = appService.getAppTitle();
-            const locale = configManager.getConfig('crowi', 'app:globalLang');
+            const locale = configManager.getConfig('app:globalLang');
             const template = path.join(crowi.localeDir, `${locale}/admin/userWaitingActivation.ejs`);
             const url = appService.getSiteUrl();
 
@@ -218,7 +218,7 @@ async function makeRegistrationEmailToken(email, crowi) {
     throw Error('mailService is not setup');
   }
 
-  const locale = configManager.getConfig('crowi', 'app:globalLang');
+  const locale = configManager.getConfig('app:globalLang');
   const appUrl = appService.getSiteUrl();
 
   const userRegistrationOrder = await UserRegistrationOrder.createUserRegistrationOrder(email);
@@ -248,7 +248,7 @@ export const registerAction = (crowi) => {
     const registerForm = req.body.registerForm || {};
     const email = registerForm.email;
     const isRegisterableEmail = await User.isRegisterableEmail(email);
-    const registrationMode = configManager.getConfig('crowi', 'security:registrationMode') as RegistrationMode;
+    const registrationMode = configManager.getConfig('security:registrationMode');
     const isEmailValid = await User.isEmailValid(email);
 
     if (registrationMode === RegistrationMode.CLOSED) {

+ 5 - 5
apps/app/src/server/routes/apiv3/users.js

@@ -146,7 +146,7 @@ module.exports = (crowi) => {
   const sendEmailByUserList = async(userList) => {
     const { appService, mailService } = crowi;
     const appTitle = appService.getAppTitle();
-    const locale = configManager.getConfig('crowi', 'app:globalLang');
+    const locale = configManager.getConfig('app:globalLang');
     const failedToSendEmailList = [];
 
     for (const user of userList) {
@@ -181,7 +181,7 @@ module.exports = (crowi) => {
   const sendEmailByUser = async(user) => {
     const { appService, mailService } = crowi;
     const appTitle = appService.getAppTitle();
-    const locale = configManager.getConfig('crowi', 'app:globalLang');
+    const locale = configManager.getConfig('app:globalLang');
 
     await mailService.send({
       to: user.email,
@@ -366,7 +366,7 @@ module.exports = (crowi) => {
       return res.apiv3Err(new ErrorV3('find-user-is-not-found'));
     }
 
-    const limit = parseInt(req.query.limit) || await configManager.getConfig('crowi', 'customize:showPageLimitationM') || 30;
+    const limit = parseInt(req.query.limit) || await configManager.getConfig('customize:showPageLimitationM') || 30;
     const page = req.query.page;
     const offset = (page - 1) * limit;
     const queryOptions = { offset, limit };
@@ -793,8 +793,8 @@ module.exports = (crowi) => {
    */
   router.delete('/:id/remove', loginRequiredStrictly, adminRequired, certifyUserOperationOtherThenYourOwn, addActivity, async(req, res) => {
     const { id } = req.params;
-    const isUsersHomepageDeletionEnabled = configManager.getConfig('crowi', 'security:user-homepage-deletion:isEnabled');
-    const isForceDeleteUserHomepageOnUserDeletion = configManager.getConfig('crowi', 'security:user-homepage-deletion:isForceDeleteUserHomepageOnUserDeletion');
+    const isUsersHomepageDeletionEnabled = configManager.getConfig('security:user-homepage-deletion:isEnabled');
+    const isForceDeleteUserHomepageOnUserDeletion = configManager.getConfig('security:user-homepage-deletion:isForceDeleteUserHomepageOnUserDeletion');
 
     try {
       const user = await User.findById(id);

+ 1 - 1
apps/app/src/server/routes/forgot-password.ts

@@ -15,7 +15,7 @@ const logger = loggerFactory('growi:routes:forgot-password');
 export const checkForgotPasswordEnabledMiddlewareFactory = (crowi: any, forApi = false) => {
 
   return (req: Request, res: Response, next: NextFunction): void => {
-    const isPasswordResetEnabled = crowi.configManager.getConfig('crowi', 'security:passport-local:isPasswordResetEnabled') as boolean | null;
+    const isPasswordResetEnabled = crowi.configManager.getConfig('security:passport-local:isPasswordResetEnabled');
     const isLocalStrategySetup = crowi.passportService.isLocalStrategySetup as boolean ?? false;
 
     const isEnabled = isLocalStrategySetup && isPasswordResetEnabled;

+ 10 - 10
apps/app/src/server/routes/login-passport.js

@@ -344,7 +344,7 @@ module.exports = function(crowi, app) {
   };
 
   const loginPassportGoogleCallback = async(req, res, next) => {
-    const globalLang = crowi.configManager.getConfig('crowi', 'app:globalLang');
+    const globalLang = crowi.configManager.getConfig('app:globalLang');
 
     const providerId = 'google';
     const strategyName = 'google';
@@ -457,10 +457,10 @@ module.exports = function(crowi, app) {
   const loginPassportOidcCallback = async(req, res, next) => {
     const providerId = 'oidc';
     const strategyName = 'oidc';
-    const attrMapId = crowi.configManager.getConfig('crowi', 'security:passport-oidc:attrMapId');
-    const attrMapUserName = crowi.configManager.getConfig('crowi', 'security:passport-oidc:attrMapUserName');
-    const attrMapName = crowi.configManager.getConfig('crowi', 'security:passport-oidc:attrMapName');
-    const attrMapMail = crowi.configManager.getConfig('crowi', 'security:passport-oidc:attrMapMail');
+    const attrMapId = crowi.configManager.getConfig('security:passport-oidc:attrMapId');
+    const attrMapUserName = crowi.configManager.getConfig('security:passport-oidc:attrMapUserName');
+    const attrMapName = crowi.configManager.getConfig('security:passport-oidc:attrMapName');
+    const attrMapMail = crowi.configManager.getConfig('security:passport-oidc:attrMapMail');
 
     let response;
     try {
@@ -506,11 +506,11 @@ module.exports = function(crowi, app) {
   const loginPassportSamlCallback = async(req, res, next) => {
     const providerId = 'saml';
     const strategyName = 'saml';
-    const attrMapId = crowi.configManager.getConfig('crowi', 'security:passport-saml:attrMapId');
-    const attrMapUsername = crowi.configManager.getConfig('crowi', 'security:passport-saml:attrMapUsername');
-    const attrMapMail = crowi.configManager.getConfig('crowi', 'security:passport-saml:attrMapMail');
-    const attrMapFirstName = crowi.configManager.getConfig('crowi', 'security:passport-saml:attrMapFirstName') || 'firstName';
-    const attrMapLastName = crowi.configManager.getConfig('crowi', 'security:passport-saml:attrMapLastName') || 'lastName';
+    const attrMapId = crowi.configManager.getConfig('security:passport-saml:attrMapId');
+    const attrMapUsername = crowi.configManager.getConfig('security:passport-saml:attrMapUsername');
+    const attrMapMail = crowi.configManager.getConfig('security:passport-saml:attrMapMail');
+    const attrMapFirstName = crowi.configManager.getConfig('security:passport-saml:attrMapFirstName') || 'firstName';
+    const attrMapLastName = crowi.configManager.getConfig('security:passport-saml:attrMapLastName') || 'lastName';
 
     let response;
     try {

+ 3 - 3
apps/app/src/server/routes/login.js

@@ -20,7 +20,7 @@ module.exports = function(crowi, app) {
     // send mails to all admin users (derived from crowi) -- 2020.06.18 Yuki Takei
     const admins = await User.findAdmins();
     const appTitle = appService.getAppTitle();
-    const locale = configManager.getConfig('crowi', 'app:globalLang');
+    const locale = configManager.getConfig('app:globalLang');
 
     const promises = admins.map((admin) => {
       return mailService.send({
@@ -134,7 +134,7 @@ module.exports = function(crowi, app) {
     }
 
     // config で closed ならさよなら
-    if (configManager.getConfig('crowi', 'security:registrationMode') === aclService.labels.SECURITY_REGISTRATION_MODE_CLOSED) {
+    if (configManager.getConfig('security:registrationMode') === aclService.labels.SECURITY_REGISTRATION_MODE_CLOSED) {
       return res.apiv3Err('message.registration_closed', 403);
     }
 
@@ -169,7 +169,7 @@ module.exports = function(crowi, app) {
         return res.apiv3Err(errors, 400);
       }
 
-      const registrationMode = configManager.getConfig('crowi', 'security:registrationMode');
+      const registrationMode = configManager.getConfig('security:registrationMode');
 
       User.createUserByEmailAndPassword(name, username, email, password, undefined, async(err, userData) => {
         if (err) {

+ 2 - 2
apps/app/src/server/routes/ogp.ts

@@ -61,7 +61,7 @@ module.exports = function(crowi) {
 
   const renderOgp = async(req: Request, res: Response) => {
 
-    const ogpUri = configManager.getConfig('crowi', 'app:ogpUri');
+    const ogpUri = configManager.getConfig('app:ogpUri');
 
     if (ogpUri == null) {
       return res.status(501).send('OGP_URI for growi-unique-ogp has not been setup');
@@ -124,7 +124,7 @@ module.exports = function(crowi) {
   const ogpValidator = async(req:Request, res:Response, next:NextFunction) => {
     const { aclService, fileUploadService, configManager } = crowi;
 
-    const ogpUri = configManager.getConfig('crowi', 'app:ogpUri');
+    const ogpUri = configManager.getConfig('app:ogpUri');
 
     if (ogpUri == null) return res.status(400).send('OGP URI for GROWI has not been setup');
     if (!fileUploadService.getIsUploadable()) return res.status(501).send('This GROWI can not upload file');

+ 10 - 10
apps/app/src/server/service/acl.integ.ts

@@ -34,7 +34,7 @@ describe('AclService test', () => {
 
       const result = aclService.isAclEnabled();
 
-      const wikiMode = configManager.getConfig('crowi', 'security:wikiMode');
+      const wikiMode = configManager.getConfig('security:wikiMode');
       expect(wikiMode).toBe(undefined);
       expect(result).toBe(true);
     });
@@ -47,7 +47,7 @@ describe('AclService test', () => {
 
       const result = aclService.isAclEnabled();
 
-      const wikiMode = configManager.getConfig('crowi', 'security:wikiMode');
+      const wikiMode = configManager.getConfig('security:wikiMode');
       expect(wikiMode).toBe('dummy string');
       expect(result).toBe(true);
     });
@@ -60,7 +60,7 @@ describe('AclService test', () => {
 
       const result = aclService.isAclEnabled();
 
-      const wikiMode = configManager.getConfig('crowi', 'security:wikiMode');
+      const wikiMode = configManager.getConfig('security:wikiMode');
       expect(wikiMode).toBe('private');
       expect(result).toBe(true);
     });
@@ -73,7 +73,7 @@ describe('AclService test', () => {
 
       const result = aclService.isAclEnabled();
 
-      const wikiMode = configManager.getConfig('crowi', 'security:wikiMode');
+      const wikiMode = configManager.getConfig('security:wikiMode');
       expect(wikiMode).toBe('public');
       expect(result).toBe(false);
     });
@@ -91,7 +91,7 @@ describe('AclService test', () => {
 
       const result = aclService.isWikiModeForced();
 
-      const wikiMode = configManager.getConfig('crowi', 'security:wikiMode');
+      const wikiMode = configManager.getConfig('security:wikiMode');
       expect(wikiMode).toBe(undefined);
       expect(result).toBe(false);
     });
@@ -104,7 +104,7 @@ describe('AclService test', () => {
 
       const result = aclService.isWikiModeForced();
 
-      const wikiMode = configManager.getConfig('crowi', 'security:wikiMode');
+      const wikiMode = configManager.getConfig('security:wikiMode');
       expect(wikiMode).toBe('dummy string');
       expect(result).toBe(false);
     });
@@ -117,7 +117,7 @@ describe('AclService test', () => {
 
       const result = aclService.isWikiModeForced();
 
-      const wikiMode = configManager.getConfig('crowi', 'security:wikiMode');
+      const wikiMode = configManager.getConfig('security:wikiMode');
       expect(wikiMode).toBe('private');
       expect(result).toBe(true);
     });
@@ -130,7 +130,7 @@ describe('AclService test', () => {
 
       const result = aclService.isWikiModeForced();
 
-      const wikiMode = configManager.getConfig('crowi', 'security:wikiMode');
+      const wikiMode = configManager.getConfig('security:wikiMode');
       expect(wikiMode).toBe('public');
       expect(result).toBe(true);
     });
@@ -154,7 +154,7 @@ describe('AclService test', () => {
 
       const result = aclService.isGuestAllowedToRead();
 
-      const wikiMode = configManager.getConfig('crowi', 'security:wikiMode');
+      const wikiMode = configManager.getConfig('security:wikiMode');
       expect(wikiMode).toBe('private');
       expect(getConfigSpy).not.toHaveBeenCalledWith('crowi', 'security:restrictGuestMode');
       expect(result).toBe(false);
@@ -168,7 +168,7 @@ describe('AclService test', () => {
 
       const result = aclService.isGuestAllowedToRead();
 
-      const wikiMode = configManager.getConfig('crowi', 'security:wikiMode');
+      const wikiMode = configManager.getConfig('security:wikiMode');
       expect(wikiMode).toBe('public');
       expect(getConfigSpy).not.toHaveBeenCalledWith('crowi', 'security:restrictGuestMode');
       expect(result).toBe(true);

+ 4 - 4
apps/app/src/server/service/acl.ts

@@ -32,7 +32,7 @@ class AclServiceImpl implements AclService {
    * @returns Whether Access Control is enabled or not
    */
   isAclEnabled() {
-    const wikiMode = configManager.getConfig('crowi', 'security:wikiMode');
+    const wikiMode = configManager.getConfig('security:wikiMode');
     return wikiMode !== 'public';
   }
 
@@ -40,7 +40,7 @@ class AclServiceImpl implements AclService {
    * @returns Whether wiki mode is set
    */
   isWikiModeForced() {
-    const wikiMode = configManager.getConfig('crowi', 'security:wikiMode');
+    const wikiMode = configManager.getConfig('security:wikiMode');
     const isPrivateOrPublic = wikiMode === 'private' || wikiMode === 'public';
 
     return isPrivateOrPublic;
@@ -50,7 +50,7 @@ class AclServiceImpl implements AclService {
    * @returns Whether guest users are allowed to read public pages
    */
   isGuestAllowedToRead() {
-    const wikiMode = configManager.getConfig('crowi', 'security:wikiMode');
+    const wikiMode = configManager.getConfig('security:wikiMode');
 
     // return false if private wiki mode
     if (wikiMode === 'private') {
@@ -61,7 +61,7 @@ class AclServiceImpl implements AclService {
       return true;
     }
 
-    const guestMode = configManager.getConfig('crowi', 'security:restrictGuestMode');
+    const guestMode = configManager.getConfig('security:restrictGuestMode');
 
     // 'Readonly' => returns true (allow access to guests)
     // 'Deny', null, undefined, '', ... everything else => returns false (requires login)

+ 5 - 5
apps/app/src/server/service/activity.ts

@@ -73,10 +73,10 @@ class ActivityService {
   }
 
   getAvailableActions = function(isIncludeEssentialActions = true): SupportedActionType[] {
-    const auditLogEnabled = this.crowi.configManager.getConfig('crowi', 'app:auditLogEnabled') || false;
-    const auditLogActionGroupSize = this.crowi.configManager.getConfig('crowi', 'app:auditLogActionGroupSize') || ActionGroupSize.Small;
-    const auditLogAdditionalActions = this.crowi.configManager.getConfig('crowi', 'app:auditLogAdditionalActions');
-    const auditLogExcludeActions = this.crowi.configManager.getConfig('crowi', 'app:auditLogExcludeActions');
+    const auditLogEnabled = this.crowi.configManager.getConfig('app:auditLogEnabled') || false;
+    const auditLogActionGroupSize = this.crowi.configManager.getConfig('app:auditLogActionGroupSize') || ActionGroupSize.Small;
+    const auditLogAdditionalActions = this.crowi.configManager.getConfig('app:auditLogAdditionalActions');
+    const auditLogExcludeActions = this.crowi.configManager.getConfig('app:auditLogExcludeActions');
 
     if (!auditLogEnabled) {
       return AllEssentialActions;
@@ -135,7 +135,7 @@ class ActivityService {
 
   createTtlIndex = async function() {
     const configManager = this.crowi.configManager;
-    const activityExpirationSeconds = configManager != null ? configManager.getConfig('crowi', 'app:activityExpirationSeconds') : 2592000;
+    const activityExpirationSeconds = configManager != null ? configManager.getConfig('app:activityExpirationSeconds') : 2592000;
 
     try {
       // create the collection with indexes at first

+ 6 - 6
apps/app/src/server/service/app.ts

@@ -33,7 +33,7 @@ export default class AppService implements S2sMessageHandlable {
       return false;
     }
 
-    const isInstalled = configManager.getConfig('crowi', 'app:installed');
+    const isInstalled = configManager.getConfig('app:installed');
 
     return !isInstalled;
   }
@@ -73,7 +73,7 @@ export default class AppService implements S2sMessageHandlable {
   }
 
   getAppTitle() {
-    return configManager.getConfig('crowi', 'app:title') ?? 'GROWI';
+    return configManager.getConfig('app:title') ?? 'GROWI';
   }
 
   /**
@@ -87,7 +87,7 @@ export default class AppService implements S2sMessageHandlable {
    */
   /* eslint-disable no-else-return */
   getSiteUrl() {
-    const siteUrl = configManager.getConfig('crowi', 'app:siteUrl');
+    const siteUrl = configManager.getConfig('app:siteUrl');
     if (siteUrl != null) {
       return pathUtils.removeTrailingSlash(siteUrl);
     }
@@ -98,11 +98,11 @@ export default class AppService implements S2sMessageHandlable {
   /* eslint-enable no-else-return */
 
   getTzoffset() {
-    return -(configManager.getConfig('crowi', 'app:timezone') || 9) * 60;
+    return -(configManager.getConfig('app:timezone') || 9) * 60;
   }
 
   getAppConfidential() {
-    return configManager.getConfig('crowi', 'app:confidential');
+    return configManager.getConfig('app:confidential');
   }
 
   async isDBInitialized(forceReload) {
@@ -119,7 +119,7 @@ export default class AppService implements S2sMessageHandlable {
   }
 
   isMaintenanceMode(): boolean {
-    return configManager.getConfig('crowi', 'app:isMaintenanceMode');
+    return configManager.getConfig('app:isMaintenanceMode');
   }
 
   async startMaintenanceMode(): Promise<void> {

+ 5 - 5
apps/app/src/server/service/customize.ts

@@ -91,7 +91,7 @@ class CustomizeService implements S2sMessageHandlable {
    * initialize custom css strings
    */
   initCustomCss() {
-    const rawCss = this.configManager.getConfig('crowi', 'customize:css') || '';
+    const rawCss = this.configManager.getConfig('customize:css') || '';
 
     // uglify and store
     this.customCss = uglifycss.processString(rawCss);
@@ -104,15 +104,15 @@ class CustomizeService implements S2sMessageHandlable {
   }
 
   getCustomScript() {
-    return this.configManager.getConfig('crowi', 'customize:script');
+    return this.configManager.getConfig('customize:script');
   }
 
   getCustomNoscript() {
-    return this.configManager.getConfig('crowi', 'customize:noscript');
+    return this.configManager.getConfig('customize:noscript');
   }
 
   initCustomTitle() {
-    let configValue = this.configManager.getConfig('crowi', 'customize:title');
+    let configValue = this.configManager.getConfig('customize:title');
 
     if (configValue == null || configValue.trim().length === 0) {
       configValue = '{{pagename}} - {{sitename}}';
@@ -124,7 +124,7 @@ class CustomizeService implements S2sMessageHandlable {
   }
 
   async initGrowiTheme(): Promise<void> {
-    const theme = this.configManager.getConfig('crowi', 'customize:theme');
+    const theme = this.configManager.getConfig('customize:theme');
 
     this.theme = theme;
 

+ 16 - 16
apps/app/src/server/service/file-uploader/aws.ts

@@ -67,7 +67,7 @@ const isValidObjectCannedACL = (acl: string | undefined): acl is ObjectCannedACL
  * @returns ObjectCannedACL
  */
 const getS3PutObjectCannedAcl = (): ObjectCannedACL | undefined => {
-  const s3ObjectCannedACL = configManager.getConfig('crowi', 'aws:s3ObjectCannedACL');
+  const s3ObjectCannedACL = configManager.getConfig('aws:s3ObjectCannedACL');
   if (isValidObjectCannedACL(s3ObjectCannedACL)) {
     return s3ObjectCannedACL;
   }
@@ -75,12 +75,12 @@ const getS3PutObjectCannedAcl = (): ObjectCannedACL | undefined => {
 };
 
 const getS3Bucket = (): string | undefined => {
-  return configManager.getConfig('crowi', 'aws:s3Bucket') ?? undefined; // return undefined when getConfig() returns null
+  return configManager.getConfig('aws:s3Bucket') ?? undefined; // return undefined when getConfig() returns null
 };
 
 const S3Factory = (): S3Client => {
-  const accessKeyId = configManager.getConfig('crowi', 'aws:s3AccessKeyId');
-  const secretAccessKey = configManager.getConfig('crowi', 'aws:s3SecretAccessKey');
+  const accessKeyId = configManager.getConfig('aws:s3AccessKeyId');
+  const secretAccessKey = configManager.getConfig('aws:s3SecretAccessKey');
 
   return new S3Client({
     credentials: accessKeyId != null && secretAccessKey != null
@@ -89,9 +89,9 @@ const S3Factory = (): S3Client => {
         secretAccessKey,
       }
       : undefined,
-    region: configManager.getConfig('crowi', 'aws:s3Region'),
-    endpoint: configManager.getConfig('crowi', 'aws:s3CustomEndpoint'),
-    forcePathStyle: configManager.getConfig('crowi', 'aws:s3CustomEndpoint') != null, // s3ForcePathStyle renamed to forcePathStyle in v3
+    region: configManager.getConfig('aws:s3Region'),
+    endpoint: configManager.getConfig('aws:s3CustomEndpoint'),
+    forcePathStyle: configManager.getConfig('aws:s3CustomEndpoint') != null, // s3ForcePathStyle renamed to forcePathStyle in v3
   });
 };
 
@@ -144,7 +144,7 @@ class AwsFileUploader extends AbstractFileUploader {
    * @inheritdoc
    */
   override determineResponseMode() {
-    return configManager.getConfig('crowi', 'aws:referenceFileWithRelayMode')
+    return configManager.getConfig('aws:referenceFileWithRelayMode')
       ? ResponseMode.RELAY
       : ResponseMode.REDIRECT;
   }
@@ -232,7 +232,7 @@ class AwsFileUploader extends AbstractFileUploader {
 
     const s3 = S3Factory();
     const filePath = getFilePathOnStorage(attachment);
-    const lifetimeSecForTemporaryUrl = configManager.getConfig('crowi', 'aws:lifetimeSecForTemporaryUrl');
+    const lifetimeSecForTemporaryUrl = configManager.getConfig('aws:lifetimeSecForTemporaryUrl');
 
     // issue signed url (default: expires 120 seconds)
     // https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getSignedUrl-property
@@ -261,13 +261,13 @@ module.exports = (crowi) => {
   const lib = new AwsFileUploader(crowi);
 
   lib.isValidUploadSettings = function() {
-    return configManager.getConfig('crowi', 'aws:s3AccessKeyId') != null
-      && configManager.getConfig('crowi', 'aws:s3SecretAccessKey') != null
+    return configManager.getConfig('aws:s3AccessKeyId') != null
+      && configManager.getConfig('aws:s3SecretAccessKey') != null
       && (
-        configManager.getConfig('crowi', 'aws:s3Region') != null
-          || configManager.getConfig('crowi', 'aws:s3CustomEndpoint') != null
+        configManager.getConfig('aws:s3Region') != null
+          || configManager.getConfig('aws:s3CustomEndpoint') != null
       )
-      && configManager.getConfig('crowi', 'aws:s3Bucket') != null;
+      && configManager.getConfig('aws:s3Bucket') != null;
   };
 
   (lib as any).deleteFile = async function(attachment) {
@@ -326,8 +326,8 @@ module.exports = (crowi) => {
   };
 
   (lib as any).checkLimit = async function(uploadFileSize) {
-    const maxFileSize = configManager.getConfig('crowi', 'app:maxFileSize');
-    const totalLimit = configManager.getConfig('crowi', 'app:fileUploadTotalLimit');
+    const maxFileSize = configManager.getConfig('app:maxFileSize');
+    const totalLimit = configManager.getConfig('app:fileUploadTotalLimit');
     return lib.doCheckLimit(uploadFileSize, maxFileSize, totalLimit);
   };
 

+ 11 - 11
apps/app/src/server/service/file-uploader/azure.ts

@@ -45,8 +45,8 @@ type AzureConfig = {
 
 
 function getAzureConfig(): AzureConfig {
-  const accountName = configManager.getConfig('crowi', 'azure:storageAccountName');
-  const containerName = configManager.getConfig('crowi', 'azure:storageContainerName');
+  const accountName = configManager.getConfig('azure:storageAccountName');
+  const containerName = configManager.getConfig('azure:storageContainerName');
 
   if (accountName == null || containerName == null) {
     throw new Error('Azure Blob Storage is not configured.');
@@ -59,9 +59,9 @@ function getAzureConfig(): AzureConfig {
 }
 
 function getCredential(): TokenCredential {
-  const tenantId = configManager.getConfig('crowi', 'azure:tenantId');
-  const clientId = configManager.getConfig('crowi', 'azure:clientId');
-  const clientSecret = configManager.getConfig('crowi', 'azure:clientSecret');
+  const tenantId = configManager.getConfig('azure:tenantId');
+  const clientId = configManager.getConfig('azure:clientId');
+  const clientSecret = configManager.getConfig('azure:clientSecret');
 
   if (tenantId == null || clientId == null || clientSecret == null) {
     throw new Error(`Azure Blob Storage missing required configuration: tenantId=${tenantId}, clientId=${clientId}, clientSecret=${clientSecret}`);
@@ -145,7 +145,7 @@ class AzureFileUploader extends AbstractFileUploader {
    * @inheritdoc
    */
   override determineResponseMode() {
-    return configManager.getConfig('crowi', 'azure:referenceFileWithRelayMode')
+    return configManager.getConfig('azure:referenceFileWithRelayMode')
       ? ResponseMode.RELAY
       : ResponseMode.REDIRECT;
   }
@@ -189,7 +189,7 @@ class AzureFileUploader extends AbstractFileUploader {
       throw new Error('Azure Blob is not configured.');
     }
 
-    const lifetimeSecForTemporaryUrl = configManager.getConfig('crowi', 'azure:lifetimeSecForTemporaryUrl');
+    const lifetimeSecForTemporaryUrl = configManager.getConfig('azure:lifetimeSecForTemporaryUrl');
 
     const url = await (async() => {
       const containerClient = await getContainerClient();
@@ -241,8 +241,8 @@ module.exports = (crowi) => {
   const lib = new AzureFileUploader(crowi);
 
   lib.isValidUploadSettings = function() {
-    return configManager.getConfig('crowi', 'azure:storageAccountName') != null
-      && configManager.getConfig('crowi', 'azure:storageContainerName') != null;
+    return configManager.getConfig('azure:storageAccountName') != null
+      && configManager.getConfig('azure:storageContainerName') != null;
   };
 
   (lib as any).deleteFile = async function(attachment) {
@@ -279,8 +279,8 @@ module.exports = (crowi) => {
   };
 
   (lib as any).checkLimit = async function(uploadFileSize) {
-    const maxFileSize = configManager.getConfig('crowi', 'app:maxFileSize');
-    const gcsTotalLimit = configManager.getConfig('crowi', 'app:fileUploadTotalLimit');
+    const maxFileSize = configManager.getConfig('app:maxFileSize');
+    const gcsTotalLimit = configManager.getConfig('app:fileUploadTotalLimit');
     return lib.doCheckLimit(uploadFileSize, maxFileSize, gcsTotalLimit);
   };
 

+ 5 - 5
apps/app/src/server/service/file-uploader/file-uploader.ts

@@ -52,7 +52,7 @@ export abstract class AbstractFileUploader implements FileUploader {
   }
 
   getIsUploadable() {
-    return !configManager.getConfig('crowi', 'app:fileUploadDisabled') && this.isValidUploadSettings();
+    return !configManager.getConfig('app:fileUploadDisabled') && this.isValidUploadSettings();
   }
 
   /**
@@ -91,7 +91,7 @@ export abstract class AbstractFileUploader implements FileUploader {
       return false;
     }
 
-    return !!configManager.getConfig('crowi', 'app:fileUpload');
+    return !!configManager.getConfig('app:fileUpload');
   }
 
   abstract listFiles();
@@ -107,10 +107,10 @@ export abstract class AbstractFileUploader implements FileUploader {
    * @returns file upload total limit in bytes
    */
   getFileUploadTotalLimit() {
-    const fileUploadTotalLimit = configManager.getConfig('crowi', 'app:fileUploadType') === 'mongodb'
+    const fileUploadTotalLimit = configManager.getConfig('app:fileUploadType') === 'mongodb'
       // Use app:fileUploadTotalLimit if gridfs:totalLimit is null (default for gridfs:totalLimit is null)
-      ? configManager.getConfig('crowi', 'gridfs:totalLimit') ?? configManager.getConfig('crowi', 'app:fileUploadTotalLimit')
-      : configManager.getConfig('crowi', 'app:fileUploadTotalLimit');
+      ? configManager.getConfig('app:fileUploadTotalLimit')
+      : configManager.getConfig('app:fileUploadTotalLimit');
     return fileUploadTotalLimit;
   }
 

+ 10 - 10
apps/app/src/server/service/file-uploader/gcs.ts

@@ -19,7 +19,7 @@ const logger = loggerFactory('growi:service:fileUploaderGcs');
 
 
 function getGcsBucket(): string {
-  const gcsBucket = configManager.getConfig('crowi', 'gcs:bucket');
+  const gcsBucket = configManager.getConfig('gcs:bucket');
   if (gcsBucket == null) {
     throw new Error('GCS bucket is not configured.');
   }
@@ -29,7 +29,7 @@ function getGcsBucket(): string {
 let storage: Storage;
 function getGcsInstance() {
   if (storage == null) {
-    const keyFilename = configManager.getConfig('crowi', 'gcs:apiKeyJsonPath');
+    const keyFilename = configManager.getConfig('gcs:apiKeyJsonPath');
     // see https://googleapis.dev/nodejs/storage/latest/Storage.html
     storage = keyFilename != null
       ? new Storage({ keyFilename }) // Create a client with explicit credentials
@@ -39,7 +39,7 @@ function getGcsInstance() {
 }
 
 function getFilePathOnStorage(attachment) {
-  const namespace = configManager.getConfig('crowi', 'gcs:uploadNamespace');
+  const namespace = configManager.getConfig('gcs:uploadNamespace');
   const dirName = (attachment.page != null)
     ? 'attachment'
     : 'user';
@@ -101,7 +101,7 @@ class GcsFileUploader extends AbstractFileUploader {
    * @inheritdoc
    */
   override determineResponseMode() {
-    return configManager.getConfig('crowi', 'gcs:referenceFileWithRelayMode')
+    return configManager.getConfig('gcs:referenceFileWithRelayMode')
       ? ResponseMode.RELAY
       : ResponseMode.REDIRECT;
   }
@@ -175,7 +175,7 @@ class GcsFileUploader extends AbstractFileUploader {
     const myBucket = gcs.bucket(getGcsBucket());
     const filePath = getFilePathOnStorage(attachment);
     const file = myBucket.file(filePath);
-    const lifetimeSecForTemporaryUrl = configManager.getConfig('crowi', 'gcs:lifetimeSecForTemporaryUrl');
+    const lifetimeSecForTemporaryUrl = configManager.getConfig('gcs:lifetimeSecForTemporaryUrl');
 
     // issue signed url (default: expires 120 seconds)
     // https://cloud.google.com/storage/docs/access-control/signed-urls
@@ -202,8 +202,8 @@ module.exports = function(crowi: Crowi) {
   const lib = new GcsFileUploader(crowi);
 
   lib.isValidUploadSettings = function() {
-    return configManager.getConfig('crowi', 'gcs:apiKeyJsonPath') != null
-      && configManager.getConfig('crowi', 'gcs:bucket') != null;
+    return configManager.getConfig('gcs:apiKeyJsonPath') != null
+      && configManager.getConfig('gcs:bucket') != null;
   };
 
   (lib as any).deleteFile = function(attachment) {
@@ -249,8 +249,8 @@ module.exports = function(crowi: Crowi) {
    * - per-file size limit (specified by MAX_FILE_SIZE)
    */
   (lib as any).checkLimit = async function(uploadFileSize) {
-    const maxFileSize = configManager.getConfig('crowi', 'app:maxFileSize');
-    const gcsTotalLimit = configManager.getConfig('crowi', 'app:fileUploadTotalLimit');
+    const maxFileSize = configManager.getConfig('app:maxFileSize');
+    const gcsTotalLimit = configManager.getConfig('app:fileUploadTotalLimit');
     return lib.doCheckLimit(uploadFileSize, maxFileSize, gcsTotalLimit);
   };
 
@@ -265,7 +265,7 @@ module.exports = function(crowi: Crowi) {
     const gcs = getGcsInstance();
     const bucket = gcs.bucket(getGcsBucket());
     const [files] = await bucket.getFiles({
-      prefix: configManager.getConfig('crowi', 'gcs:uploadNamespace'),
+      prefix: configManager.getConfig('gcs:uploadNamespace'),
     });
 
     return files.map(({ name, metadata: { size } }) => {

+ 1 - 1
apps/app/src/server/service/file-uploader/gridfs.ts

@@ -166,7 +166,7 @@ module.exports = function(crowi) {
    * - mongodb(gridfs) size limit (specified by MONGO_GRIDFS_TOTAL_LIMIT)
    */
   (lib as any).checkLimit = async function(uploadFileSize) {
-    const maxFileSize = configManager.getConfig('crowi', 'app:maxFileSize');
+    const maxFileSize = configManager.getConfig('app:maxFileSize');
     const totalLimit = lib.getFileUploadTotalLimit();
     return lib.doCheckLimit(uploadFileSize, maxFileSize, totalLimit);
   };

+ 1 - 1
apps/app/src/server/service/file-uploader/index.ts

@@ -21,7 +21,7 @@ const envToModuleMappings = {
 };
 
 export const getUploader = (crowi: Crowi): FileUploader => {
-  const method = envToModuleMappings[configManager.getConfig('crowi', 'app:fileUploadType')];
+  const method = envToModuleMappings[configManager.getConfig('app:fileUploadType')];
   const modulePath = `./${method}`;
   const uploader = require(modulePath)(crowi);
 

+ 4 - 4
apps/app/src/server/service/file-uploader/local.ts

@@ -68,7 +68,7 @@ class LocalFileUploader extends AbstractFileUploader {
    * @inheritdoc
    */
   override determineResponseMode() {
-    return configManager.getConfig('crowi', 'fileUpload:local:useInternalRedirect')
+    return configManager.getConfig('fileUpload:local:useInternalRedirect')
       ? ResponseMode.DELEGATE
       : ResponseMode.RELAY;
   }
@@ -211,8 +211,8 @@ module.exports = function(crowi) {
    * - per-file size limit (specified by MAX_FILE_SIZE)
    */
   (lib as any).checkLimit = async function(uploadFileSize) {
-    const maxFileSize = configManager.getConfig('crowi', 'app:maxFileSize');
-    const totalLimit = configManager.getConfig('crowi', 'app:fileUploadTotalLimit');
+    const maxFileSize = configManager.getConfig('app:maxFileSize');
+    const totalLimit = configManager.getConfig('app:fileUploadTotalLimit');
     return lib.doCheckLimit(uploadFileSize, maxFileSize, totalLimit);
   };
 
@@ -225,7 +225,7 @@ module.exports = function(crowi) {
     // Responce using internal redirect of nginx or Apache.
     const storagePath = getFilePathOnStorage(attachment);
     const relativePath = path.relative(crowi.publicDir, storagePath);
-    const internalPathRoot = configManager.getConfig('crowi', 'fileUpload:local:internalRedirectPath');
+    const internalPathRoot = configManager.getConfig('fileUpload:local:internalRedirectPath');
     const internalPath = urljoin(internalPathRoot, relativePath);
 
     const isDownload = opts?.download ?? false;

+ 12 - 12
apps/app/src/server/service/g2g-transfer.ts

@@ -285,7 +285,7 @@ export class G2GTransferPusherService implements Pusher {
       };
     }
 
-    if (configManager.getConfig('crowi', 'app:fileUploadType') === 'none') {
+    if (configManager.getConfig('app:fileUploadType') === 'none') {
       return {
         canTransfer: false,
         // TODO: i18n for reason
@@ -438,7 +438,7 @@ export class G2GTransferPusherService implements Pusher {
     const targetConfigKeys = UPLOAD_CONFIG_KEYS;
 
     const uploadConfigs = Object.fromEntries(targetConfigKeys.map((key) => {
-      return [key, configManager.getConfig('crowi', key)];
+      return [key, configManager.getConfig(key)];
     }));
 
     let zipFileStream: ReadStream;
@@ -551,13 +551,13 @@ export class G2GTransferReceiverService implements Receiver {
 
   public async answerGROWIInfo(): Promise<IDataGROWIInfo> {
     const { version, fileUploadService } = this.crowi;
-    const userUpperLimit = configManager.getConfig('crowi', 'security:userUpperLimit');
-    const fileUploadDisabled = configManager.getConfig('crowi', 'app:fileUploadDisabled');
+    const userUpperLimit = configManager.getConfig('security:userUpperLimit');
+    const fileUploadDisabled = configManager.getConfig('app:fileUploadDisabled');
     const fileUploadTotalLimit = fileUploadService.getFileUploadTotalLimit();
     const isWritable = await fileUploadService.isWritable();
 
     const attachmentInfo: IDataGROWIInfo['attachmentInfo'] = {
-      type: configManager.getConfig('crowi', 'app:fileUploadType'),
+      type: configManager.getConfig('app:fileUploadType'),
       writable: isWritable,
       bucket: undefined,
       customEndpoint: undefined, // for S3
@@ -569,16 +569,16 @@ export class G2GTransferReceiverService implements Receiver {
     // put storage location info to check storage identification
     switch (attachmentInfo.type) {
       case 'aws':
-        attachmentInfo.bucket = configManager.getConfig('crowi', 'aws:s3Bucket');
-        attachmentInfo.customEndpoint = configManager.getConfig('crowi', 'aws:s3CustomEndpoint');
+        attachmentInfo.bucket = configManager.getConfig('aws:s3Bucket');
+        attachmentInfo.customEndpoint = configManager.getConfig('aws:s3CustomEndpoint');
         break;
       case 'gcs':
-        attachmentInfo.bucket = configManager.getConfig('crowi', 'gcs:bucket');
-        attachmentInfo.uploadNamespace = configManager.getConfig('crowi', 'gcs:uploadNamespace');
+        attachmentInfo.bucket = configManager.getConfig('gcs:bucket');
+        attachmentInfo.uploadNamespace = configManager.getConfig('gcs:uploadNamespace');
         break;
       case 'azure':
-        attachmentInfo.accountName = configManager.getConfig('crowi', 'azure:storageAccountName');
-        attachmentInfo.containerName = configManager.getConfig('crowi', 'azure:storageContainerName');
+        attachmentInfo.accountName = configManager.getConfig('azure:storageAccountName');
+        attachmentInfo.containerName = configManager.getConfig('azure:storageContainerName');
         break;
       default:
     }
@@ -650,7 +650,7 @@ export class G2GTransferReceiverService implements Receiver {
     const { appService } = this.crowi;
     const importService = getImportService();
     /** whether to keep current file upload configs */
-    const shouldKeepUploadConfigs = configManager.getConfig('crowi', 'app:fileUploadType') !== 'none';
+    const shouldKeepUploadConfigs = configManager.getConfig('app:fileUploadType') !== 'none';
 
     if (shouldKeepUploadConfigs) {
       /** cache file upload configs */

+ 1 - 1
apps/app/src/server/service/global-notification/global-notification-mail.js

@@ -51,7 +51,7 @@ class GlobalNotificationMailService {
    * @return  {{ subject: string, template: string, vars: object }}
    */
   generateOption(event, page, triggeredBy, { comment, oldPath }) {
-    const locale = configManager.getConfig('crowi', 'app:globalLang');
+    const locale = configManager.getConfig('app:globalLang');
     // validate for all events
     if (event == null || page == null || triggeredBy == null) {
       throw new Error(`invalid vars supplied to GlobalNotificationMailService.generateOption for event ${event}`);

+ 2 - 2
apps/app/src/server/service/global-notification/index.js

@@ -67,9 +67,9 @@ class GlobalNotificationService {
       case this.Page.GRANT_SPECIFIED:
         return false;
       case this.Page.GRANT_OWNER:
-        return (this.crowi.configManager.getConfig('notification', 'notification:owner-page:isEnabled') || false);
+        return (this.crowi.configManager.getConfig('notification:owner-page:isEnabled') || false);
       case this.Page.GRANT_USER_GROUP:
-        return (this.crowi.configManager.getConfig('notification', 'notification:group-page:isEnabled') || false);
+        return (this.crowi.configManager.getConfig('notification:group-page:isEnabled') || false);
     }
   }
 

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

@@ -42,7 +42,7 @@ type Opts = {
 }
 
 export async function getTranslation(opts?: Opts): Promise<Translation> {
-  const globalLang = configManager.getConfig('crowi', 'app:globalLang') as Lang;
+  const globalLang = configManager.getConfig('app:globalLang');
   const fixedLang = opts?.lang ?? globalLang;
 
   const initOptions: InitOptions = {

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

@@ -166,7 +166,7 @@ export class ImportService {
 
     await configManager.loadConfigs();
 
-    const currentIsV5Compatible = configManager.getConfig('crowi', 'app:isV5Compatible');
+    const currentIsV5Compatible = configManager.getConfig('app:isV5Compatible');
     const isImportPagesCollection = collections.includes('pages');
     const shouldNormalizePages = currentIsV5Compatible && isImportPagesCollection;
 

+ 2 - 2
apps/app/src/server/service/ldap.ts

@@ -163,8 +163,8 @@ class LdapService {
   }
 
   getGroupSearchBase(): string {
-    return configManager.getConfig('crowi', 'external-user-group:ldap:groupSearchBase')
-      ?? configManager.getConfig('crowi', 'security:passport-ldap:groupSearchBase')
+    return configManager.getConfig('external-user-group:ldap:groupSearchBase')
+      ?? configManager.getConfig('security:passport-ldap:groupSearchBase')
       ?? '';
   }
 

+ 10 - 10
apps/app/src/server/service/mail.ts

@@ -90,12 +90,12 @@ class MailService implements S2sMessageHandlable {
 
     this.isMailerSetup = false;
 
-    if (!configManager.getConfig('crowi', 'mail:from')) {
+    if (!configManager.getConfig('mail:from')) {
       this.mailer = null;
       return;
     }
 
-    const transmissionMethod = configManager.getConfig('crowi', 'mail:transmissionMethod');
+    const transmissionMethod = configManager.getConfig('mail:transmissionMethod');
 
     if (transmissionMethod === 'smtp') {
       this.mailer = this.createSMTPClient();
@@ -111,7 +111,7 @@ class MailService implements S2sMessageHandlable {
       this.isMailerSetup = true;
     }
 
-    this.mailConfig.from = configManager.getConfig('crowi', 'mail:from');
+    this.mailConfig.from = configManager.getConfig('mail:from');
     this.mailConfig.subject = `${appService.getAppTitle()}からのメール`;
 
     logger.debug('mailer initialized');
@@ -122,8 +122,8 @@ class MailService implements S2sMessageHandlable {
 
     logger.debug('createSMTPClient option', option);
     if (!option) {
-      const host = configManager.getConfig('crowi', 'mail:smtpHost');
-      const port = configManager.getConfig('crowi', 'mail:smtpPort');
+      const host = configManager.getConfig('mail:smtpHost');
+      const port = configManager.getConfig('mail:smtpPort');
 
       if (host == null || port == null) {
         return null;
@@ -133,10 +133,10 @@ class MailService implements S2sMessageHandlable {
         port,
       };
 
-      if (configManager.getConfig('crowi', 'mail:smtpUser') && configManager.getConfig('crowi', 'mail:smtpPassword')) {
+      if (configManager.getConfig('mail:smtpPassword')) {
         option.auth = {
-          user: configManager.getConfig('crowi', 'mail:smtpUser'),
-          pass: configManager.getConfig('crowi', 'mail:smtpPassword'),
+          user: configManager.getConfig('mail:smtpUser'),
+          pass: configManager.getConfig('mail:smtpPassword'),
         };
       }
       if (option.port === 465) {
@@ -156,8 +156,8 @@ class MailService implements S2sMessageHandlable {
     const { configManager } = this;
 
     if (!option) {
-      const accessKeyId = configManager.getConfig('crowi', 'mail:sesAccessKeyId');
-      const secretAccessKey = configManager.getConfig('crowi', 'mail:sesSecretAccessKey');
+      const accessKeyId = configManager.getConfig('mail:sesAccessKeyId');
+      const secretAccessKey = configManager.getConfig('mail:sesSecretAccessKey');
       if (accessKeyId == null || secretAccessKey == null) {
         return null;
       }

+ 1 - 1
apps/app/src/server/service/page/delete-completely-user-home-by-system.integ.ts

@@ -40,7 +40,7 @@ describe('delete-completely-user-home-by-system test', () => {
     // setup config
     await configManager.loadConfigs();
     await configManager.updateConfig('app:isV5Compatible', true);
-    const isV5Compatible = configManager.getConfig('crowi', 'app:isV5Compatible');
+    const isV5Compatible = configManager.getConfig('app:isV5Compatible');
     expect(isV5Compatible).toBeTruthy();
 
     // setup user documents

+ 12 - 12
apps/app/src/server/service/page/index.ts

@@ -223,8 +223,8 @@ class PageService implements IPageService {
   ): boolean {
     if (operator == null || isTopPage(page.path) || isUsersTopPage(page.path)) return false;
 
-    const pageCompleteDeletionAuthority = configManager.getConfig('crowi', 'security:pageCompleteDeletionAuthority');
-    const pageRecursiveCompleteDeletionAuthority = configManager.getConfig('crowi', 'security:pageRecursiveCompleteDeletionAuthority');
+    const pageCompleteDeletionAuthority = configManager.getConfig('security:pageCompleteDeletionAuthority');
+    const pageRecursiveCompleteDeletionAuthority = configManager.getConfig('security:pageRecursiveCompleteDeletionAuthority');
 
     if (!this.canDeleteCompletelyAsMultiGroupGrantedPage(page, creatorId, operator, userRelatedGroups)) return false;
 
@@ -241,7 +241,7 @@ class PageService implements IPageService {
   canDeleteCompletelyAsMultiGroupGrantedPage(
       page: PageDocument, creatorId: ObjectIdLike | null, operator: any | null, userRelatedGroups: PopulatedGrantedGroup[],
   ): boolean {
-    const pageCompleteDeletionAuthority = configManager.getConfig('crowi', 'security:pageCompleteDeletionAuthority');
+    const pageCompleteDeletionAuthority = configManager.getConfig('security:pageCompleteDeletionAuthority');
     const isAllGroupMembershipRequiredForPageCompleteDeletion = configManager.getConfig(
       'crowi', 'security:isAllGroupMembershipRequiredForPageCompleteDeletion',
     );
@@ -281,8 +281,8 @@ class PageService implements IPageService {
   canDelete(page: PageDocument, creatorId: ObjectIdLike | null, operator: any | null, isRecursively: boolean): boolean {
     if (operator == null || isTopPage(page.path) || isUsersTopPage(page.path)) return false;
 
-    const pageDeletionAuthority = configManager.getConfig('crowi', 'security:pageDeletionAuthority');
-    const pageRecursiveDeletionAuthority = configManager.getConfig('crowi', 'security:pageRecursiveDeletionAuthority');
+    const pageDeletionAuthority = configManager.getConfig('security:pageDeletionAuthority');
+    const pageRecursiveDeletionAuthority = configManager.getConfig('security:pageRecursiveDeletionAuthority');
 
     const [singleAuthority, recursiveAuthority] = prepareDeleteConfigValuesForCalc(pageDeletionAuthority, pageRecursiveDeletionAuthority);
 
@@ -290,7 +290,7 @@ class PageService implements IPageService {
   }
 
   canDeleteUserHomepageByConfig(): boolean {
-    return configManager.getConfig('crowi', 'security:user-homepage-deletion:isEnabled') ?? false;
+    return configManager.getConfig('security:user-homepage-deletion:isEnabled') ?? false;
   }
 
   async isUsersHomepageOwnerAbsent(path: string): Promise<boolean> {
@@ -481,7 +481,7 @@ class PageService implements IPageService {
   private shouldUseV4ProcessForRevert(page): boolean {
     const Page = mongoose.model('Page') as unknown as PageModel;
 
-    const isV5Compatible = configManager.getConfig('crowi', 'app:isV5Compatible');
+    const isV5Compatible = configManager.getConfig('app:isV5Compatible');
     const isPageRestricted = page.grant === Page.GRANT_RESTRICTED;
 
     const shouldUseV4Process = !isV5Compatible || isPageRestricted;
@@ -3771,7 +3771,7 @@ class PageService implements IPageService {
    */
   async create(_path: string, body: string, user: HasObjectId, options: IOptionsForCreate = {}): Promise<HydratedDocument<PageDocument>> {
     // Switch method
-    const isV5Compatible = configManager.getConfig('crowi', 'app:isV5Compatible');
+    const isV5Compatible = configManager.getConfig('app:isV5Compatible');
     if (!isV5Compatible) {
       return this.createV4(_path, body, user, options);
     }
@@ -3902,7 +3902,7 @@ class PageService implements IPageService {
 
     const format = options.format || 'markdown';
     const grantUserGroupIds = options.grantUserGroupIds || null;
-    const expandContentWidth = configManager.getConfig('crowi', 'customize:isContainerFluid');
+    const expandContentWidth = configManager.getConfig('customize:isContainerFluid');
 
     // sanitize path
     path = generalXssFilter.process(path); // eslint-disable-line no-param-reassign
@@ -3979,7 +3979,7 @@ class PageService implements IPageService {
   async forceCreateBySystem(path: string, body: string, options: IOptionsForCreate & { grantUserIds?: ObjectIdLike[] }): Promise<PageDocument> {
     const Page = mongoose.model('Page') as unknown as PageModel;
 
-    const isV5Compatible = configManager.getConfig('crowi', 'app:isV5Compatible');
+    const isV5Compatible = configManager.getConfig('app:isV5Compatible');
     if (!isV5Compatible) {
       throw Error('This method is available only when v5 compatible');
     }
@@ -4148,7 +4148,7 @@ class PageService implements IPageService {
     const Page = mongoose.model<HydratedDocument<PageDocument>, PageModel>('Page');
 
     const wasOnTree = pageData.parent != null || isTopPage(pageData.path);
-    const isV5Compatible = configManager.getConfig('crowi', 'app:isV5Compatible');
+    const isV5Compatible = configManager.getConfig('app:isV5Compatible');
 
     const shouldUseV4Process = this.shouldUseUpdatePageV4(pageData.grant, isV5Compatible, wasOnTree);
     if (shouldUseV4Process) {
@@ -4462,7 +4462,7 @@ class PageService implements IPageService {
   }
 
   async createTtlIndex(): Promise<void> {
-    const wipPageExpirationSeconds = configManager.getConfig('crowi', 'app:wipPageExpirationSeconds') ?? 172800;
+    const wipPageExpirationSeconds = configManager.getConfig('app:wipPageExpirationSeconds') ?? 172800;
     const collection = mongoose.connection.collection('pages');
 
     try {

+ 1 - 1
apps/app/src/server/service/page/should-use-v4-process.ts

@@ -10,7 +10,7 @@ export const shouldUseV4Process = (page: IPage): boolean => {
 
   const isTrashPage = page.status === Page.STATUS_DELETED;
   const isPageMigrated = page.parent != null;
-  const isV5Compatible = configManager.getConfig('crowi', 'app:isV5Compatible');
+  const isV5Compatible = configManager.getConfig('app:isV5Compatible');
   const isRoot = isTopPage(page.path);
   const isPageRestricted = page.grant === Page.GRANT_RESTRICTED;
 

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

@@ -229,7 +229,7 @@ class PassportService implements S2sMessageHandlable {
 
     const { configManager } = this.crowi;
 
-    const isEnabled = configManager.getConfig('crowi', 'security:passport-local:isEnabled');
+    const isEnabled = configManager.getConfig('security:passport-local:isEnabled');
 
     // when disabled
     if (!isEnabled) {
@@ -285,7 +285,7 @@ class PassportService implements S2sMessageHandlable {
     const config = this.crowi.config;
     const { configManager } = this.crowi;
 
-    const isLdapEnabled = configManager.getConfig('crowi', 'security:passport-ldap:isEnabled');
+    const isLdapEnabled = configManager.getConfig('security:passport-ldap:isEnabled');
 
     // when disabled
     if (!isLdapEnabled) {
@@ -315,7 +315,7 @@ class PassportService implements S2sMessageHandlable {
    * @memberof PassportService
    */
   getLdapAttrNameMappedToUsername() {
-    return this.crowi.configManager.getConfig('crowi', 'security:passport-ldap:attrMapUsername') || 'uid';
+    return this.crowi.configManager.getConfig('security:passport-ldap:attrMapUsername') || 'uid';
   }
 
   /**
@@ -325,7 +325,7 @@ class PassportService implements S2sMessageHandlable {
    * @memberof PassportService
    */
   getLdapAttrNameMappedToName() {
-    return this.crowi.configManager.getConfig('crowi', 'security:passport-ldap:attrMapName') || '';
+    return this.crowi.configManager.getConfig('security:passport-ldap:attrMapName') || '';
   }
 
   /**
@@ -335,7 +335,7 @@ class PassportService implements S2sMessageHandlable {
    * @memberof PassportService
    */
   getLdapAttrNameMappedToMail() {
-    return this.crowi.configManager.getConfig('crowi', 'security:passport-ldap:attrMapMail') || 'mail';
+    return this.crowi.configManager.getConfig('security:passport-ldap:attrMapMail') || 'mail';
   }
 
   /**
@@ -363,14 +363,14 @@ class PassportService implements S2sMessageHandlable {
     const { configManager } = this.crowi;
 
     // get configurations
-    const isUserBind        = configManager.getConfig('crowi', 'security:passport-ldap:isUserBind');
-    const serverUrl         = configManager.getConfig('crowi', 'security:passport-ldap:serverUrl');
-    const bindDN            = configManager.getConfig('crowi', 'security:passport-ldap:bindDN');
-    const bindCredentials   = configManager.getConfig('crowi', 'security:passport-ldap:bindDNPassword');
-    const searchFilter      = configManager.getConfig('crowi', 'security:passport-ldap:searchFilter') || '(uid={{username}})';
-    const groupSearchBase   = configManager.getConfig('crowi', 'security:passport-ldap:groupSearchBase');
-    const groupSearchFilter = configManager.getConfig('crowi', 'security:passport-ldap:groupSearchFilter');
-    const groupDnProperty   = configManager.getConfig('crowi', 'security:passport-ldap:groupDnProperty') || 'uid';
+    const isUserBind        = configManager.getConfig('security:passport-ldap:isUserBind');
+    const serverUrl         = configManager.getConfig('security:passport-ldap:serverUrl');
+    const bindDN            = configManager.getConfig('security:passport-ldap:bindDN');
+    const bindCredentials   = configManager.getConfig('security:passport-ldap:bindDNPassword');
+    const searchFilter      = configManager.getConfig('security:passport-ldap:searchFilter') || '(uid={{username}})';
+    const groupSearchBase   = configManager.getConfig('security:passport-ldap:groupSearchBase');
+    const groupSearchFilter = configManager.getConfig('security:passport-ldap:groupSearchFilter');
+    const groupDnProperty   = configManager.getConfig('security:passport-ldap:groupDnProperty') || 'uid';
     /* eslint-enable no-multi-spaces */
 
     // parse serverUrl
@@ -447,7 +447,7 @@ class PassportService implements S2sMessageHandlable {
     this.resetGoogleStrategy();
 
     const { configManager } = this.crowi;
-    const isGoogleEnabled = configManager.getConfig('crowi', 'security:passport-google:isEnabled');
+    const isGoogleEnabled = configManager.getConfig('security:passport-google:isEnabled');
 
     // when disabled
     if (!isGoogleEnabled) {
@@ -458,11 +458,11 @@ class PassportService implements S2sMessageHandlable {
     passport.use(
       new GoogleStrategy(
         {
-          clientID: configManager.getConfig('crowi', 'security:passport-google:clientId'),
-          clientSecret: configManager.getConfig('crowi', 'security:passport-google:clientSecret'),
+          clientID: configManager.getConfig('security:passport-google:clientId'),
+          clientSecret: configManager.getConfig('security:passport-google:clientSecret'),
           callbackURL: (this.crowi.appService.getSiteUrl() != null)
             ? urljoin(this.crowi.appService.getSiteUrl(), '/passport/google/callback') // auto-generated with v3.2.4 and above
-            : configManager.getConfig('crowi', 'security:passport-google:callbackUrl'), // DEPRECATED: backward compatible with v3.2.3 and below
+            : configManager.getConfig('security:passport-google:callbackUrl'), // DEPRECATED: backward compatible with v3.2.3 and below
           skipUserProfile: false,
         },
         (accessToken, refreshToken, profile, done) => {
@@ -495,7 +495,7 @@ class PassportService implements S2sMessageHandlable {
     this.resetGitHubStrategy();
 
     const { configManager } = this.crowi;
-    const isGitHubEnabled = configManager.getConfig('crowi', 'security:passport-github:isEnabled');
+    const isGitHubEnabled = configManager.getConfig('security:passport-github:isEnabled');
 
     // when disabled
     if (!isGitHubEnabled) {
@@ -506,11 +506,11 @@ class PassportService implements S2sMessageHandlable {
     passport.use(
       new GitHubStrategy(
         {
-          clientID: configManager.getConfig('crowi', 'security:passport-github:clientId'),
-          clientSecret: configManager.getConfig('crowi', 'security:passport-github:clientSecret'),
+          clientID: configManager.getConfig('security:passport-github:clientId'),
+          clientSecret: configManager.getConfig('security:passport-github:clientSecret'),
           callbackURL: (this.crowi.appService.getSiteUrl() != null)
             ? urljoin(this.crowi.appService.getSiteUrl(), '/passport/github/callback') // auto-generated with v3.2.4 and above
-            : configManager.getConfig('crowi', 'security:passport-github:callbackUrl'), // DEPRECATED: backward compatible with v3.2.3 and below
+            : configManager.getConfig('security:passport-github:callbackUrl'), // DEPRECATED: backward compatible with v3.2.3 and below
           skipUserProfile: false,
         },
         (accessToken, refreshToken, profile, done) => {
@@ -543,7 +543,7 @@ class PassportService implements S2sMessageHandlable {
     this.resetOidcStrategy();
 
     const { configManager } = this.crowi;
-    const isOidcEnabled = configManager.getConfig('crowi', 'security:passport-oidc:isEnabled');
+    const isOidcEnabled = configManager.getConfig('security:passport-oidc:isEnabled');
 
     // when disabled
     if (!isOidcEnabled) {
@@ -554,19 +554,19 @@ class PassportService implements S2sMessageHandlable {
 
     // setup client
     // extend oidc request timeouts
-    const OIDC_ISSUER_TIMEOUT_OPTION = await this.crowi.configManager.getConfig('crowi', 'security:passport-oidc:oidcIssuerTimeoutOption');
+    const OIDC_ISSUER_TIMEOUT_OPTION = await this.crowi.configManager.getConfig('security:passport-oidc:oidcIssuerTimeoutOption');
     // OIDCIssuer.defaultHttpOptions = { timeout: OIDC_ISSUER_TIMEOUT_OPTION };
 
     custom.setHttpOptionsDefaults({
       timeout: OIDC_ISSUER_TIMEOUT_OPTION,
     });
 
-    const issuerHost = configManager.getConfig('crowi', 'security:passport-oidc:issuerHost');
-    const clientId = configManager.getConfig('crowi', 'security:passport-oidc:clientId');
-    const clientSecret = configManager.getConfig('crowi', 'security:passport-oidc:clientSecret');
-    const redirectUri = (configManager.getConfig('crowi', 'app:siteUrl') != null)
+    const issuerHost = configManager.getConfig('security:passport-oidc:issuerHost');
+    const clientId = configManager.getConfig('security:passport-oidc:clientId');
+    const clientSecret = configManager.getConfig('security:passport-oidc:clientSecret');
+    const redirectUri = (configManager.getConfig('app:siteUrl') != null)
       ? urljoin(this.crowi.appService.getSiteUrl(), '/passport/oidc/callback')
-      : configManager.getConfig('crowi', 'security:passport-oidc:callbackUrl'); // DEPRECATED: backward compatible with v3.2.3 and below
+      : configManager.getConfig('security:passport-oidc:callbackUrl'); // DEPRECATED: backward compatible with v3.2.3 and below
 
     // Prevent request timeout error on app init
     const oidcIssuer = await this.getOIDCIssuerInstance(issuerHost);
@@ -575,35 +575,35 @@ class PassportService implements S2sMessageHandlable {
 
       logger.debug('Discovered issuer %s %O', oidcIssuer.issuer, oidcIssuer.metadata);
 
-      const authorizationEndpoint = configManager.getConfig('crowi', 'security:passport-oidc:authorizationEndpoint');
+      const authorizationEndpoint = configManager.getConfig('security:passport-oidc:authorizationEndpoint');
       if (authorizationEndpoint) {
         oidcIssuerMetadata.authorization_endpoint = authorizationEndpoint;
       }
-      const tokenEndpoint = configManager.getConfig('crowi', 'security:passport-oidc:tokenEndpoint');
+      const tokenEndpoint = configManager.getConfig('security:passport-oidc:tokenEndpoint');
       if (tokenEndpoint) {
         oidcIssuerMetadata.token_endpoint = tokenEndpoint;
       }
-      const revocationEndpoint = configManager.getConfig('crowi', 'security:passport-oidc:revocationEndpoint');
+      const revocationEndpoint = configManager.getConfig('security:passport-oidc:revocationEndpoint');
       if (revocationEndpoint) {
         oidcIssuerMetadata.revocation_endpoint = revocationEndpoint;
       }
-      const introspectionEndpoint = configManager.getConfig('crowi', 'security:passport-oidc:introspectionEndpoint');
+      const introspectionEndpoint = configManager.getConfig('security:passport-oidc:introspectionEndpoint');
       if (introspectionEndpoint) {
         oidcIssuerMetadata.introspection_endpoint = introspectionEndpoint;
       }
-      const userInfoEndpoint = configManager.getConfig('crowi', 'security:passport-oidc:userInfoEndpoint');
+      const userInfoEndpoint = configManager.getConfig('security:passport-oidc:userInfoEndpoint');
       if (userInfoEndpoint) {
         oidcIssuerMetadata.userinfo_endpoint = userInfoEndpoint;
       }
-      const endSessionEndpoint = configManager.getConfig('crowi', 'security:passport-oidc:endSessionEndpoint');
+      const endSessionEndpoint = configManager.getConfig('security:passport-oidc:endSessionEndpoint');
       if (endSessionEndpoint) {
         oidcIssuerMetadata.end_session_endpoint = endSessionEndpoint;
       }
-      const registrationEndpoint = configManager.getConfig('crowi', 'security:passport-oidc:registrationEndpoint');
+      const registrationEndpoint = configManager.getConfig('security:passport-oidc:registrationEndpoint');
       if (registrationEndpoint) {
         oidcIssuerMetadata.registration_endpoint = registrationEndpoint;
       }
-      const jwksUri = configManager.getConfig('crowi', 'security:passport-oidc:jwksUri');
+      const jwksUri = configManager.getConfig('security:passport-oidc:jwksUri');
       if (jwksUri) {
         oidcIssuerMetadata.jwks_uri = jwksUri;
       }
@@ -620,7 +620,7 @@ class PassportService implements S2sMessageHandlable {
       });
       // prevent error AssertionError [ERR_ASSERTION]: id_token issued in the future
       // Doc: https://github.com/panva/node-openid-client/tree/v2.x#allow-for-system-clock-skew
-      const OIDC_CLIENT_CLOCK_TOLERANCE = await this.crowi.configManager.getConfig('crowi', 'security:passport-oidc:oidcClientClockTolerance');
+      const OIDC_CLIENT_CLOCK_TOLERANCE = await this.crowi.configManager.getConfig('security:passport-oidc:oidcClientClockTolerance');
       client[custom.clock_tolerance] = OIDC_CLIENT_CLOCK_TOLERANCE;
       passport.use('oidc', new OidcStrategy(
         {
@@ -713,9 +713,9 @@ class PassportService implements S2sMessageHandlable {
    * @returns instance of OIDCIssuer
    */
   async getOIDCIssuerInstance(issuerHost: string): Promise<void | OIDCIssuer> {
-    const OIDC_TIMEOUT_MULTIPLIER = await this.crowi.configManager.getConfig('crowi', 'security:passport-oidc:timeoutMultiplier');
-    const OIDC_DISCOVERY_RETRIES = await this.crowi.configManager.getConfig('crowi', 'security:passport-oidc:discoveryRetries');
-    const OIDC_ISSUER_TIMEOUT_OPTION = await this.crowi.configManager.getConfig('crowi', 'security:passport-oidc:oidcIssuerTimeoutOption');
+    const OIDC_TIMEOUT_MULTIPLIER = await this.crowi.configManager.getConfig('security:passport-oidc:timeoutMultiplier');
+    const OIDC_DISCOVERY_RETRIES = await this.crowi.configManager.getConfig('security:passport-oidc:discoveryRetries');
+    const OIDC_ISSUER_TIMEOUT_OPTION = await this.crowi.configManager.getConfig('security:passport-oidc:oidcIssuerTimeoutOption');
     const oidcIssuerHostReady = await this.isOidcHostReachable(issuerHost);
     if (!oidcIssuerHostReady) {
       logger.error('OidcStrategy: setup failed');
@@ -749,7 +749,7 @@ class PassportService implements S2sMessageHandlable {
     this.resetSamlStrategy();
 
     const { configManager } = this.crowi;
-    const isSamlEnabled = configManager.getConfig('crowi', 'security:passport-saml:isEnabled');
+    const isSamlEnabled = configManager.getConfig('security:passport-saml:isEnabled');
 
     // when disabled
     if (!isSamlEnabled) {
@@ -760,12 +760,12 @@ class PassportService implements S2sMessageHandlable {
     passport.use(
       new SamlStrategy(
         {
-          entryPoint: configManager.getConfig('crowi', 'security:passport-saml:entryPoint'),
+          entryPoint: configManager.getConfig('security:passport-saml:entryPoint'),
           callbackUrl: (this.crowi.appService.getSiteUrl() != null)
             ? urljoin(this.crowi.appService.getSiteUrl(), '/passport/saml/callback') // auto-generated with v3.2.4 and above
-            : configManager.getConfig('crowi', 'security:passport-saml:callbackUrl'), // DEPRECATED: backward compatible with v3.2.3 and below
-          issuer: configManager.getConfig('crowi', 'security:passport-saml:issuer'),
-          cert: configManager.getConfig('crowi', 'security:passport-saml:cert'),
+            : configManager.getConfig('security:passport-saml:callbackUrl'), // DEPRECATED: backward compatible with v3.2.3 and below
+          issuer: configManager.getConfig('security:passport-saml:issuer'),
+          cert: configManager.getConfig('security:passport-saml:cert'),
           disableRequestedAuthnContext: true,
         },
         (profile: Profile, done: VerifiedCallback) => {
@@ -799,7 +799,7 @@ class PassportService implements S2sMessageHandlable {
   getSamlMissingMandatoryConfigKeys() {
     const missingRequireds: string[] = [];
     for (const key of this.mandatoryConfigKeysForSaml) {
-      if (this.crowi.configManager.getConfig('crowi', key) == null) {
+      if (this.crowi.configManager.getConfig(key) == null) {
         missingRequireds.push(key);
       }
     }
@@ -822,7 +822,7 @@ class PassportService implements S2sMessageHandlable {
    * Verify that a SAML response meets the attribute-base login control rule
    */
   verifySAMLResponseByABLCRule(response) {
-    const rule = this.crowi.configManager.getConfig('crowi', 'security:passport-saml:ABLCRule');
+    const rule = this.crowi.configManager.getConfig('security:passport-saml:ABLCRule');
     if (rule == null) {
       logger.debug('There is no ABLCRule.');
       return true;
@@ -974,12 +974,12 @@ class PassportService implements S2sMessageHandlable {
 
   isSameUsernameTreatedAsIdenticalUser(providerType) {
     const key = `security:passport-${providerType}:isSameUsernameTreatedAsIdenticalUser`;
-    return this.crowi.configManager.getConfig('crowi', key);
+    return this.crowi.configManager.getConfig(key);
   }
 
   isSameEmailTreatedAsIdenticalUser(providerType) {
     const key = `security:passport-${providerType}:isSameEmailTreatedAsIdenticalUser`;
-    return this.crowi.configManager.getConfig('crowi', key);
+    return this.crowi.configManager.getConfig(key);
   }
 
   literalUnescape(string: string) {

+ 4 - 4
apps/app/src/server/service/rest-qiita-API.js

@@ -20,8 +20,8 @@ class RestQiitaAPIService {
   constructor(crowi) {
     this.crowi = crowi;
     this.configManager = crowi.configManager;
-    this.team = this.configManager.getConfig('crowi', 'importer:qiita:team_name');
-    this.token = this.configManager.getConfig('crowi', 'importer:qiita:access_token');
+    this.team = this.configManager.getConfig('importer:qiita:team_name');
+    this.token = this.configManager.getConfig('importer:qiita:access_token');
     this.axios = getAxios(this.team, this.token);
   }
 
@@ -31,8 +31,8 @@ class RestQiitaAPIService {
    * @param {string} token
    */
   async reset() {
-    this.team = this.configManager.getConfig('crowi', 'importer:qiita:team_name');
-    this.token = this.configManager.getConfig('crowi', 'importer:qiita:access_token');
+    this.team = this.configManager.getConfig('importer:qiita:team_name');
+    this.token = this.configManager.getConfig('importer:qiita:access_token');
     this.axios = getAxios(this.team, this.token);
   }
 

+ 2 - 2
apps/app/src/server/service/s2s-messaging/index.ts

@@ -15,7 +15,7 @@ const envToModuleMappings = {
 //   provide: S2sMessagingService,
 //   deps: [ConfigManager],
 //   useFactory(configManager: ConfigManager) {
-//     const type = configManager.getConfig('crowi', 's2sMessagingPubsub:serverType');
+//     const type = configManager.getConfig('s2sMessagingPubsub:serverType');
 
 //     if (type == null) {
 //       logger.info('Config pub/sub server is not defined.');
@@ -43,7 +43,7 @@ class S2sMessagingServiceFactory {
   delegator!: S2sMessagingService;
 
   initializeDelegator(crowi) {
-    const type = crowi.configManager.getConfig('crowi', 's2sMessagingPubsub:serverType');
+    const type = crowi.configManager.getConfig('s2sMessagingPubsub:serverType');
 
     if (type == null) {
       logger.info('Config pub/sub server is not defined.');

+ 4 - 4
apps/app/src/server/service/s2s-messaging/nchan.ts

@@ -178,7 +178,7 @@ class NchanDelegator extends AbstractS2sMessagingService {
 module.exports = function(crowi) {
   const { configManager } = crowi;
 
-  const uri = configManager.getConfig('crowi', 'app:nchanUri');
+  const uri = configManager.getConfig('app:nchanUri');
 
   // when nachan server URI is not set
   if (uri == null) {
@@ -186,9 +186,9 @@ module.exports = function(crowi) {
     return;
   }
 
-  const publishPath = configManager.getConfig('crowi', 's2sMessagingPubsub:nchan:publishPath');
-  const subscribePath = configManager.getConfig('crowi', 's2sMessagingPubsub:nchan:subscribePath');
-  const channelId = configManager.getConfig('crowi', 's2sMessagingPubsub:nchan:channelId');
+  const publishPath = configManager.getConfig('s2sMessagingPubsub:nchan:publishPath');
+  const subscribePath = configManager.getConfig('s2sMessagingPubsub:nchan:subscribePath');
+  const channelId = configManager.getConfig('s2sMessagingPubsub:nchan:channelId');
 
   return new NchanDelegator(uri, publishPath, subscribePath, channelId);
 };

+ 9 - 9
apps/app/src/server/service/search-delegator/elasticsearch.ts

@@ -75,7 +75,7 @@ class ElasticsearchDelegator implements SearchDelegator<Data, ESTermsKey, ESQuer
     this.name = SearchDelegatorName.DEFAULT;
     this.socketIoService = socketIoService;
 
-    const elasticsearchVersion: number = configManager.getConfig('crowi', 'app:elasticsearchVersion');
+    const elasticsearchVersion: number = configManager.getConfig('app:elasticsearchVersion');
 
     if (elasticsearchVersion !== 7 && elasticsearchVersion !== 8) {
       throw new Error('Unsupported Elasticsearch version. Please specify a valid number to \'ELASTICSEARCH_VERSION\'');
@@ -83,7 +83,7 @@ class ElasticsearchDelegator implements SearchDelegator<Data, ESTermsKey, ESQuer
 
     this.isElasticsearchV7 = elasticsearchVersion === 7;
 
-    this.isElasticsearchReindexOnBoot = configManager.getConfig('crowi', 'app:elasticsearchReindexOnBoot');
+    this.isElasticsearchReindexOnBoot = configManager.getConfig('app:elasticsearchReindexOnBoot');
 
     // In Elasticsearch RegExp, we don't need to used ^ and $.
     // Ref: https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-regexp-query.html#_standard_operators
@@ -115,12 +115,12 @@ class ElasticsearchDelegator implements SearchDelegator<Data, ESTermsKey, ESQuer
   initClient() {
     const { host, auth, indexName } = this.getConnectionInfo();
 
-    const rejectUnauthorized = configManager.getConfig('crowi', 'app:elasticsearchRejectUnauthorized');
+    const rejectUnauthorized = configManager.getConfig('app:elasticsearchRejectUnauthorized');
 
     const options = {
       node: host,
       auth,
-      requestTimeout: configManager.getConfig('crowi', 'app:elasticsearchRequestTimeout'),
+      requestTimeout: configManager.getConfig('app:elasticsearchRequestTimeout'),
     };
 
     this.client = new ElasticsearchClient(this.isElasticsearchV7, options, rejectUnauthorized);
@@ -140,7 +140,7 @@ class ElasticsearchDelegator implements SearchDelegator<Data, ESTermsKey, ESQuer
     let host = this.esUri;
     let auth;
 
-    const elasticsearchUri = configManager.getConfig('crowi', 'app:elasticsearchUri');
+    const elasticsearchUri = configManager.getConfig('app:elasticsearchUri');
 
     if (elasticsearchUri != null) {
       const url = new URL(elasticsearchUri);
@@ -453,13 +453,13 @@ class ElasticsearchDelegator implements SearchDelegator<Data, ESTermsKey, ESQuer
     const countQuery = new PageQueryBuilder(queryFactory()).query;
     const totalCount = await countQuery.count();
 
-    const maxBodyLengthToIndex = configManager.getConfig('crowi', 'app:elasticsearchMaxBodyLengthToIndex');
+    const maxBodyLengthToIndex = configManager.getConfig('app:elasticsearchMaxBodyLengthToIndex');
 
     const readStream = Page.aggregate<AggregatedPage>(
       aggregatePipelineToIndex(maxBodyLengthToIndex, matchQuery),
     ).cursor();
 
-    const bulkSize: number = configManager.getConfig('crowi', 'app:elasticsearchReindexBulkSize');
+    const bulkSize: number = configManager.getConfig('app:elasticsearchReindexBulkSize');
     const batchStream = createBatchStream(bulkSize);
 
     const appendTagNamesStream = new Transform({
@@ -774,8 +774,8 @@ class ElasticsearchDelegator implements SearchDelegator<Data, ESTermsKey, ESQuer
   }
 
   async filterPagesByViewer(query, user, userGroups) {
-    const showPagesRestrictedByOwner = !configManager.getConfig('crowi', 'security:list-policy:hideRestrictedByOwner');
-    const showPagesRestrictedByGroup = !configManager.getConfig('crowi', 'security:list-policy:hideRestrictedByGroup');
+    const showPagesRestrictedByOwner = !configManager.getConfig('security:list-policy:hideRestrictedByOwner');
+    const showPagesRestrictedByGroup = !configManager.getConfig('security:list-policy:hideRestrictedByGroup');
 
     query = this.initializeBoolQuery(query); // eslint-disable-line no-param-reassign
 

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

@@ -117,7 +117,7 @@ class SearchService implements SearchQueryParser, SearchResolver {
   }
 
   get isElasticsearchEnabled() {
-    const uri = configManager.getConfig('crowi', 'app:elasticsearchUri');
+    const uri = configManager.getConfig('app:elasticsearchUri');
     return uri != null && uri.length > 0;
   }
 

+ 8 - 8
apps/app/src/server/service/slack-integration.ts

@@ -98,20 +98,20 @@ export class SlackIntegrationService implements S2sMessageHandlable {
   }
 
   get isSlackbotConfigured(): boolean {
-    const hasSlackbotType = !!this.configManager.getConfig('crowi', 'slackbot:currentBotType');
+    const hasSlackbotType = !!this.configManager.getConfig('slackbot:currentBotType');
     return hasSlackbotType;
   }
 
   get isSlackLegacyConfigured(): boolean {
     // for legacy util
-    const hasSlackToken = !!this.configManager.getConfig('notification', 'slack:token');
-    const hasSlackIwhUrl = !!this.configManager.getConfig('notification', 'slack:incomingWebhookUrl');
+    const hasSlackToken = !!this.configManager.getConfig('slack:token');
+    const hasSlackIwhUrl = !!this.configManager.getConfig('slack:incomingWebhookUrl');
 
     return hasSlackToken || hasSlackIwhUrl;
   }
 
   private isCheckTypeValid(): boolean {
-    const currentBotType = this.configManager.getConfig('crowi', 'slackbot:currentBotType');
+    const currentBotType = this.configManager.getConfig('slackbot:currentBotType');
     if (currentBotType == null) {
       throw new Error('The config \'SLACKBOT_TYPE\'(ns: \'crowi\', key: \'slackbot:currentBotType\') must be set.');
     }
@@ -120,7 +120,7 @@ export class SlackIntegrationService implements S2sMessageHandlable {
   }
 
   get proxyUriForCurrentType(): string | undefined {
-    const currentBotType = this.configManager.getConfig('crowi', 'slackbot:currentBotType');
+    const currentBotType = this.configManager.getConfig('slackbot:currentBotType');
 
     // TODO assert currentBotType is not null and CUSTOM_WITHOUT_PROXY
 
@@ -131,7 +131,7 @@ export class SlackIntegrationService implements S2sMessageHandlable {
         proxyUri = OFFICIAL_SLACKBOT_PROXY_URI;
         break;
       default:
-        proxyUri = this.configManager.getConfig('crowi', 'slackbot:proxyUri');
+        proxyUri = this.configManager.getConfig('slackbot:proxyUri');
         break;
     }
 
@@ -144,7 +144,7 @@ export class SlackIntegrationService implements S2sMessageHandlable {
   async generateClientForCustomBotWithoutProxy(): Promise<WebClient> {
     this.isCheckTypeValid();
 
-    const token = this.configManager.getConfig('crowi', 'slackbot:withoutProxy:botToken');
+    const token = this.configManager.getConfig('slackbot:withoutProxy:botToken');
 
     if (token == null) {
       throw new Error('The config \'SLACK_BOT_TOKEN\'(ns: \'crowi\', key: \'slackbot:withoutProxy:botToken\') must be set.');
@@ -178,7 +178,7 @@ export class SlackIntegrationService implements S2sMessageHandlable {
   async generateClientForPrimaryWorkspace(): Promise<WebClient> {
     this.isCheckTypeValid();
 
-    const currentBotType = this.configManager.getConfig('crowi', 'slackbot:currentBotType');
+    const currentBotType = this.configManager.getConfig('slackbot:currentBotType');
 
     if (currentBotType === SlackbotType.CUSTOM_WITHOUT_PROXY) {
       return this.generateClientForCustomBotWithoutProxy();

+ 3 - 3
apps/app/src/server/service/socket-io/socket-io.ts

@@ -177,7 +177,7 @@ export class SocketIoService {
 
       logger.debug('Current count of clients for \'/admin\':', clientsCount);
 
-      const limit = configManager.getConfig('crowi', 's2cMessagingPubsub:connectionsLimitForAdmin');
+      const limit = configManager.getConfig('s2cMessagingPubsub:connectionsLimitForAdmin');
       if (limit <= clientsCount) {
         const msg = `The connection was refused because the current count of clients for '/admin' is ${clientsCount} and exceeds the limit`;
         logger.warn(msg);
@@ -196,7 +196,7 @@ export class SocketIoService {
 
       logger.debug('Current count of clients for guests:', clientsCount);
 
-      const limit = configManager.getConfig('crowi', 's2cMessagingPubsub:connectionsLimitForGuest');
+      const limit = configManager.getConfig('s2cMessagingPubsub:connectionsLimitForGuest');
       if (limit <= clientsCount) {
         const msg = `The connection was refused because the current count of clients for guests is ${clientsCount} and exceeds the limit`;
         logger.warn(msg);
@@ -223,7 +223,7 @@ export class SocketIoService {
 
     logger.debug('Current count of clients for \'/\':', clientsCount);
 
-    const limit = configManager.getConfig('crowi', 's2cMessagingPubsub:connectionsLimit');
+    const limit = configManager.getConfig('s2cMessagingPubsub:connectionsLimit');
     if (limit <= clientsCount) {
       const msg = `The connection was refused because the current count of clients for '/' is ${clientsCount} and exceeds the limit`;
       logger.warn(msg);

+ 3 - 3
apps/app/src/server/util/importer.js

@@ -22,8 +22,8 @@ module.exports = (crowi) => {
    * Initialize importer
    */
   importer.initializeEsaClient = () => {
-    const team = configManager.getConfig('crowi', 'importer:esa:team_name');
-    const accessToken = configManager.getConfig('crowi', 'importer:esa:access_token');
+    const team = configManager.getConfig('importer:esa:team_name');
+    const accessToken = configManager.getConfig('importer:esa:access_token');
     esaClient = new Esa(accessToken, team);
     logger.debug('initialize esa importer');
   };
@@ -171,7 +171,7 @@ module.exports = (crowi) => {
    */
   const getTeamNameFromEsa = () => {
     return new Promise((resolve, reject) => {
-      const team = configManager.getConfig('crowi', 'importer:esa:team_name');
+      const team = configManager.getConfig('importer:esa:team_name');
       esaClient.team(team).then((res) => {
         resolve(res);
       }).catch((err) => {

+ 7 - 7
apps/app/src/server/util/slack-legacy.ts

@@ -15,7 +15,7 @@ interface SlackLegacyUtil {
 export const slackLegacyUtilFactory = (configManager: any): SlackLegacyUtil => {
 
   const postWithIwh = async(messageObj: IncomingWebhookSendArguments) => {
-    const webhook = new IncomingWebhook(configManager.getConfig('notification', 'slack:incomingWebhookUrl'));
+    const webhook = new IncomingWebhook(configManager.getConfig('slack:incomingWebhookUrl'));
     try {
       await webhook.send(messageObj);
     }
@@ -27,7 +27,7 @@ export const slackLegacyUtilFactory = (configManager: any): SlackLegacyUtil => {
   };
 
   const postWithWebApi = async(messageObj?: ChatPostMessageArguments) => {
-    const client = new WebClient(configManager.getConfig('notification', 'slack:token'));
+    const client = new WebClient(configManager.getConfig('slack:token'));
     try {
       await client.chat.postMessage(messageObj);
     }
@@ -41,23 +41,23 @@ export const slackLegacyUtilFactory = (configManager: any): SlackLegacyUtil => {
   return {
     postMessage: async(messageObj) => {
       // when incoming Webhooks is prioritized
-      if (configManager.getConfig('notification', 'slack:isIncomingWebhookPrioritized')) {
-        if (configManager.getConfig('notification', 'slack:incomingWebhookUrl')) {
+      if (configManager.getConfig('slack:isIncomingWebhookPrioritized')) {
+        if (configManager.getConfig('slack:incomingWebhookUrl')) {
           logger.debug('posting message with IncomingWebhook');
           return postWithIwh(messageObj as IncomingWebhookSendArguments);
         }
-        if (configManager.getConfig('notification', 'slack:token')) {
+        if (configManager.getConfig('slack:token')) {
           logger.debug('posting message with Web API');
           return postWithWebApi(messageObj as ChatPostMessageArguments);
         }
       }
       // else
       else {
-        if (configManager.getConfig('notification', 'slack:token')) {
+        if (configManager.getConfig('slack:token')) {
           logger.debug('posting message with Web API');
           return postWithWebApi(messageObj as ChatPostMessageArguments);
         }
-        if (configManager.getConfig('notification', 'slack:incomingWebhookUrl')) {
+        if (configManager.getConfig('slack:incomingWebhookUrl')) {
           logger.debug('posting message with IncomingWebhook');
           return postWithIwh(messageObj as IncomingWebhookSendArguments);
         }