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

Merge pull request #4211 from weseek/support/rename-config-key-for-slackbot

Support/rename config key for slackbot
Yuki Takei 4 лет назад
Родитель
Сommit
9cd507e475

+ 2 - 4
packages/app/.env.development

@@ -20,9 +20,7 @@ HACKMD_URI_FOR_SERVER="http://hackmd:3000"
 # DEV_HTTPS=true
 # FORCE_WIKI_MODE=private
 # PROMSTER_ENABLED=true
-# SLACK_SIGNING_SECRET=''
-# SLACK_BOT_TOKEN=''
-SALT_FOR_GTOP_TOKEN="proxy"
-SALT_FOR_PTOG_TOKEN="growi"
+# SLACKBOT_WITHOUT_PROXY_SIGNING_SECRET=''
+# SLACKBOT_WITHOUT_PROXY_BOT_TOKEN=''
 # GROWI_CLOUD_URI='http://growi.cloud'
 # GROWI_APP_ID_FOR_GROWI_CLOUD=012345

+ 5 - 2
packages/app/src/components/Admin/Notification/NotificationSetting.jsx

@@ -4,9 +4,12 @@ import React, {
 import PropTypes from 'prop-types';
 
 import {
-  Card, CardBody, TabContent, TabPane,
+  TabContent, TabPane,
 } from 'reactstrap';
 import { useTranslation } from 'react-i18next';
+
+import { SlackbotType } from '@growi/slack';
+
 import loggerFactory from '~/utils/logger';
 
 import { withUnstatedContainers } from '../../UnstatedUtils';
@@ -48,7 +51,7 @@ const SkeltonListItem = () => (
 const SlackIntegrationListItem = ({ isEnabled, currentBotType }) => {
   const { t } = useTranslation();
 
-  const isCautionVisible = currentBotType === 'officialBot' || currentBotType === 'customBotWithProxy';
+  const isCautionVisible = currentBotType === SlackbotType.OFFICIAL || currentBotType === SlackbotType.CUSTOM_WITH_PROXY;
 
   return (
     <li className="list-group-item">

+ 8 - 5
packages/app/src/components/Admin/SlackIntegration/BotTypeCard.jsx

@@ -2,17 +2,18 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import { useTranslation } from 'react-i18next';
 
+import { SlackbotType } from '@growi/slack';
 
 const botDetails = {
   officialBot: {
-    botType: 'officialBot',
+    botType: SlackbotType.OFFICIAL,
     botTypeCategory: 'official_bot',
     setUp: 'easy',
     multiWSIntegration: 'possible',
     securityControl: 'impossible',
   },
   customBotWithoutProxy: {
-    botType: 'customBotWithoutProxy',
+    botType: SlackbotType.CUSTOM_WITHOUT_PROXY,
     botTypeCategory: 'custom_bot',
     supplementaryBotName: 'without_proxy',
     setUp: 'normal',
@@ -20,7 +21,7 @@ const botDetails = {
     securityControl: 'possible',
   },
   customBotWithProxy: {
-    botType: 'customBotWithProxy',
+    botType: SlackbotType.CUSTOM_WITH_PROXY,
     botTypeCategory: 'custom_bot',
     supplementaryBotName: 'with_proxy',
     setUp: 'hard',
@@ -32,6 +33,8 @@ const botDetails = {
 const BotTypeCard = (props) => {
   const { t } = useTranslation('admin');
 
+  const isBotTypeOfficial = props.botType === SlackbotType.OFFICIAL;
+
   return (
     <div
       className={`card admin-bot-card rounded border-radius-sm shadow ${props.isActive ? 'border-primary' : ''}`}
@@ -41,7 +44,7 @@ const BotTypeCard = (props) => {
     >
       <div>
         <h3 className={`card-header mb-0 py-3
-              ${props.botType === 'officialBot' ? 'd-flex align-items-center justify-content-center' : 'text-center'}
+              ${isBotTypeOfficial ? 'd-flex align-items-center justify-content-center' : 'text-center'}
               ${props.isActive ? 'bg-primary grw-botcard-title-active' : ''}`}
         >
           <span className="mr-2">
@@ -49,7 +52,7 @@ const BotTypeCard = (props) => {
           </span>
 
           {/*  A recommended badge is shown on official bot card, supplementary names are shown on Custom bot cards   */}
-          {props.botType === 'officialBot'
+          { isBotTypeOfficial
             ? (
               <span className="badge badge-info mr-2">
                 {t('admin:slack_integration.selecting_bot_types.recommended')}

+ 3 - 3
packages/app/src/components/Admin/SlackIntegration/CustomBotWithoutProxySecretTokenSection.jsx

@@ -67,8 +67,8 @@ const CustomBotWithoutProxySecretTokenSection = (props) => {
             readOnly
           />
           <p className="form-text text-muted">
-            {/* eslint-disable-next-line react/no-danger */}
-            <small dangerouslySetInnerHTML={{ __html: t('admin:slack_integration.use_env_var_if_empty', { variable: 'SLACK_SIGNING_SECRET' }) }} />
+            {/* eslint-disable-next-line max-len, react/no-danger */}
+            <small dangerouslySetInnerHTML={{ __html: t('admin:slack_integration.use_env_var_if_empty', { variable: 'SLACKBOT_WITHOUT_PROXY_SIGNING_SECRET' }) }} />
           </p>
         </div>
 
@@ -97,7 +97,7 @@ const CustomBotWithoutProxySecretTokenSection = (props) => {
           />
           <p className="form-text text-muted">
             {/* eslint-disable-next-line react/no-danger */}
-            <small dangerouslySetInnerHTML={{ __html: t('admin:slack_integration.use_env_var_if_empty', { variable: 'SLACK_BOT_TOKEN' }) }} />
+            <small dangerouslySetInnerHTML={{ __html: t('admin:slack_integration.use_env_var_if_empty', { variable: 'SLACKBOT_WITHOUT_PROXY_BOT_TOKEN' }) }} />
           </p>
         </div>
 

+ 4 - 1
packages/app/src/components/Admin/SlackIntegration/OfficialBotSettings.jsx

@@ -1,6 +1,9 @@
 import React, { useState, useEffect, useCallback } from 'react';
 import PropTypes from 'prop-types';
 import { useTranslation } from 'react-i18next';
+
+import { SlackbotType } from '@growi/slack';
+
 import loggerFactory from '~/utils/logger';
 import AppContainer from '~/client/services/AppContainer';
 import { withUnstatedContainers } from '../../UnstatedUtils';
@@ -109,7 +112,7 @@ const OfficialBotSettings = (props) => {
                 />
               </div>
               <WithProxyAccordions
-                botType="officialBot"
+                botType={SlackbotType.OFFICIAL}
                 slackAppIntegrationId={slackAppIntegration._id}
                 tokenGtoP={tokenGtoP}
                 tokenPtoG={tokenPtoG}

+ 7 - 4
packages/app/src/components/Admin/SlackIntegration/SlackIntegration.jsx

@@ -1,6 +1,9 @@
 import React, { useState, useEffect, useCallback } from 'react';
 import PropTypes from 'prop-types';
 import { useTranslation } from 'react-i18next';
+
+import { SlackbotType } from '@growi/slack';
+
 import AppContainer from '~/client/services/AppContainer';
 import { withUnstatedContainers } from '../../UnstatedUtils';
 import { toastSuccess, toastError } from '~/client/util/apiNotification';
@@ -12,7 +15,7 @@ import ConfirmBotChangeModal from './ConfirmBotChangeModal';
 import BotTypeCard from './BotTypeCard';
 import DeleteSlackBotSettingsModal from './DeleteSlackBotSettingsModal';
 
-const botTypes = ['officialBot', 'customBotWithoutProxy', 'customBotWithProxy'];
+const botTypes = Object.values(SlackbotType);
 
 const SlackIntegration = (props) => {
 
@@ -125,7 +128,7 @@ const SlackIntegration = (props) => {
   let settingsComponent = null;
 
   switch (currentBotType) {
-    case 'officialBot':
+    case SlackbotType.OFFICIAL:
       settingsComponent = (
         <OfficialBotSettings
           slackAppIntegrations={slackAppIntegrations}
@@ -138,7 +141,7 @@ const SlackIntegration = (props) => {
         />
       );
       break;
-    case 'customBotWithoutProxy':
+    case SlackbotType.CUSTOM_WITHOUT_PROXY:
       settingsComponent = (
         <CustomBotWithoutProxySettings
           slackBotTokenEnv={slackBotTokenEnv}
@@ -151,7 +154,7 @@ const SlackIntegration = (props) => {
         />
       );
       break;
-    case 'customBotWithProxy':
+    case SlackbotType.CUSTOM_WITH_PROXY:
       settingsComponent = (
         <CustomBotWithProxySettings
           slackAppIntegrations={slackAppIntegrations}

+ 5 - 2
packages/app/src/components/Admin/SlackIntegration/WithProxyAccordions.jsx

@@ -3,6 +3,9 @@ import React, { useState } from 'react';
 import PropTypes from 'prop-types';
 import { useTranslation } from 'react-i18next';
 import { CopyToClipboard } from 'react-copy-to-clipboard';
+
+import { SlackbotType } from '@growi/slack';
+
 import loggerFactory from '~/utils/logger';
 
 import { withUnstatedContainers } from '../../UnstatedUtils';
@@ -383,7 +386,7 @@ const WithProxyAccordions = (props) => {
     },
   };
 
-  const integrationProcedureMapping = props.botType === 'officialBot' ? officialBotIntegrationProcedure : CustomBotIntegrationProcedure;
+  const integrationProcedureMapping = props.botType === SlackbotType.OFFICIAL ? officialBotIntegrationProcedure : CustomBotIntegrationProcedure;
 
   return (
     <div
@@ -416,7 +419,7 @@ const WithProxyAccordions = (props) => {
 const WithProxyAccordionsWrapper = withUnstatedContainers(WithProxyAccordions, [AppContainer]);
 WithProxyAccordions.propTypes = {
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
-  botType: PropTypes.string.isRequired,
+  botType: PropTypes.oneOf(Object.values(SlackbotType)).isRequired,
   slackAppIntegrationId: PropTypes.string.isRequired,
   tokenPtoG: PropTypes.string,
   tokenGtoP: PropTypes.string,

+ 65 - 0
packages/app/src/migrations/20210830074539-update-configs-for-slackbot.js

@@ -0,0 +1,65 @@
+import mongoose from 'mongoose';
+
+import Config from '~/server/models/config';
+import config from '^/config/migrate';
+import loggerFactory from '~/utils/logger';
+
+const logger = loggerFactory('growi:migrate:update-configs-for-slackbot');
+
+module.exports = {
+  async up(db) {
+    logger.info('Apply migration');
+    mongoose.connect(config.mongoUri, config.mongodb.options);
+
+    await Config.bulkWrite([
+      {
+        updateOne: {
+          filter: { key: 'slackbot:proxyServerUri' },
+          update: { key: 'slackbot:proxyUri' },
+        },
+      },
+      {
+        updateOne: {
+          filter: { key: 'slackbot:token' },
+          update: { key: 'slackbot:withoutProxy:botToken' },
+        },
+      },
+      {
+        updateOne: {
+          filter: { key: 'slackbot:signingSecret' },
+          update: { key: 'slackbot:withoutProxy:signingSecret' },
+        },
+      },
+    ]);
+
+    logger.info('Migration has successfully applied');
+  },
+
+  async down(db) {
+    logger.info('Rollback migration');
+    mongoose.connect(config.mongoUri, config.mongodb.options);
+
+    await Config.bulkWrite([
+      {
+        updateOne: {
+          filter: { key: 'slackbot:proxyUri' },
+          update: { key: 'slackbot:proxyServerUri' },
+        },
+      },
+      {
+        updateOne: {
+          filter: { key: 'slackbot:withoutProxy:botToken' },
+          update: { key: 'slackbot:token' },
+        },
+      },
+      {
+        updateOne: {
+          filter: { key: 'slackbot:withoutProxy:signingSecret' },
+          update: { key: 'slackbot:signingSecret' },
+        },
+      },
+    ]);
+
+    logger.info('Migration has successfully applied');
+  },
+};

+ 12 - 4
packages/app/src/server/models/slack-app-integration.js

@@ -11,12 +11,14 @@ const schema = new mongoose.Schema({
 
 class SlackAppIntegration {
 
-  static generateAccessTokens() {
+  crowi;
+
+  static generateAccessTokens(saltForGtoP, saltForPtoG) {
     const now = new Date().getTime();
     const hasher1 = crypto.createHash('sha512');
     const hasher2 = crypto.createHash('sha512');
-    const tokenGtoP = hasher1.update(`gtop${now.toString()}${process.env.SALT_FOR_GTOP_TOKEN}`).digest('base64');
-    const tokenPtoG = hasher2.update(`ptog${now.toString()}${process.env.SALT_FOR_PTOG_TOKEN}`).digest('base64');
+    const tokenGtoP = hasher1.update(`gtop-${saltForGtoP}-${now.toString()}`).digest('base64');
+    const tokenPtoG = hasher2.update(`ptog-${saltForPtoG}-${now.toString()}`).digest('base64');
     return [tokenGtoP, tokenPtoG];
   }
 
@@ -26,8 +28,12 @@ class SlackAppIntegration {
     let tokenPtoG;
     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');
+
     do {
-      generateTokens = this.generateAccessTokens();
+      generateTokens = this.generateAccessTokens(saltForGtoP, saltForPtoG);
       tokenGtoP = generateTokens[0];
       tokenPtoG = generateTokens[1];
       // eslint-disable-next-line no-await-in-loop
@@ -41,7 +47,9 @@ class SlackAppIntegration {
 }
 
 module.exports = function(crowi) {
+
   SlackAppIntegration.crowi = crowi;
+
   schema.loadClass(SlackAppIntegration);
   return mongoose.model('SlackAppIntegration', schema);
 };

+ 30 - 27
packages/app/src/server/routes/apiv3/slack-integration-settings.js

@@ -1,5 +1,8 @@
+import { SlackbotType } from '@growi/slack';
+
 import loggerFactory from '~/utils/logger';
 
+
 const mongoose = require('mongoose');
 const express = require('express');
 const { body, query, param } = require('express-validator');
@@ -61,7 +64,7 @@ module.exports = (crowi) => {
     ],
     slackIntegration: [
       body('currentBotType')
-        .isIn(['officialBot', 'customBotWithoutProxy', 'customBotWithProxy']),
+        .isIn(Object.values(SlackbotType)),
     ],
     proxyUri: [
       body('proxyUri').if(value => value !== '').trim().matches(/^(https?:\/\/)/)
@@ -102,14 +105,14 @@ module.exports = (crowi) => {
 
     const params = {
       'slackbot:currentBotType': initializedType,
-      'slackbot:signingSecret': null,
-      'slackbot:token': null,
-      'slackbot:proxyServerUri': null,
+      'slackbot:withoutProxy:signingSecret': null,
+      'slackbot:withoutProxy:botToken': null,
+      'slackbot:proxyUri': null,
     };
 
     // set url if officialBot is specified
-    if (initializedType === 'officialBot') {
-      params['slackbot:proxyServerUri'] = OFFICIAL_SLACKBOT_PROXY_URI;
+    if (initializedType === SlackbotType.OFFICIAL) {
+      params['slackbot:proxyUri'] = OFFICIAL_SLACKBOT_PROXY_URI;
     }
 
     return updateSlackBotSettings(params);
@@ -117,7 +120,7 @@ module.exports = (crowi) => {
 
   async function getConnectionStatusesFromProxy(tokens) {
     const csv = tokens.join(',');
-    const proxyUri = crowi.configManager.getConfig('crowi', 'slackbot:proxyServerUri');
+    const proxyUri = crowi.configManager.getConfig('crowi', 'slackbot:proxyUri');
 
     const result = await axios.get(urljoin(proxyUri, '/g2s/connection-status'), {
       headers: {
@@ -130,7 +133,7 @@ module.exports = (crowi) => {
   }
 
   async function requestToProxyServer(token, method, endpoint, body) {
-    const proxyUri = crowi.configManager.getConfig('crowi', 'slackbot:proxyServerUri');
+    const proxyUri = crowi.configManager.getConfig('crowi', 'slackbot:proxyUri');
     if (proxyUri == null) {
       throw new Error('Proxy URL is not registered');
     }
@@ -173,15 +176,15 @@ module.exports = (crowi) => {
 
     // retrieve settings
     const settings = {};
-    if (currentBotType === 'customBotWithoutProxy') {
-      settings.slackSigningSecretEnvVars = configManager.getConfigFromEnvVars('crowi', 'slackbot:signingSecret');
-      settings.slackBotTokenEnvVars = configManager.getConfigFromEnvVars('crowi', 'slackbot:token');
-      settings.slackSigningSecret = configManager.getConfig('crowi', 'slackbot:signingSecret');
-      settings.slackBotToken = configManager.getConfig('crowi', 'slackbot:token');
+    if (currentBotType === SlackbotType.CUSTOM_WITHOUT_PROXY) {
+      settings.slackSigningSecretEnvVars = configManager.getConfigFromEnvVars('crowi', 'slackbot:withoutProxy:signingSecret');
+      settings.slackBotTokenEnvVars = configManager.getConfigFromEnvVars('crowi', 'slackbot:withoutProxy:botToken');
+      settings.slackSigningSecret = configManager.getConfig('crowi', 'slackbot:withoutProxy:signingSecret');
+      settings.slackBotToken = configManager.getConfig('crowi', 'slackbot:withoutProxy:botToken');
     }
     else {
-      settings.proxyServerUri = crowi.configManager.getConfig('crowi', 'slackbot:proxyServerUri');
-      settings.proxyUriEnvVars = configManager.getConfigFromEnvVars('crowi', 'slackbot:proxyServerUri');
+      settings.proxyServerUri = crowi.configManager.getConfig('crowi', 'slackbot:proxyUri');
+      settings.proxyUriEnvVars = configManager.getConfigFromEnvVars('crowi', 'slackbot:proxyUri');
     }
 
     // retrieve connection statuses
@@ -191,7 +194,7 @@ module.exports = (crowi) => {
     if (currentBotType == null) {
       // no need to do anything
     }
-    else if (currentBotType === 'customBotWithoutProxy') {
+    else if (currentBotType === SlackbotType.CUSTOM_WITHOUT_PROXY) {
       const token = settings.slackBotToken;
       // check the token is not null
       if (token != null) {
@@ -333,23 +336,23 @@ module.exports = (crowi) => {
    */
   router.put('/without-proxy/update-settings', loginRequiredStrictly, adminRequired, csrf, async(req, res) => {
     const currentBotType = crowi.configManager.getConfig('crowi', 'slackbot:currentBotType');
-    if (currentBotType !== 'customBotWithoutProxy') {
+    if (currentBotType !== SlackbotType.CUSTOM_WITHOUT_PROXY) {
       const msg = 'Not CustomBotWithoutProxy';
       return res.apiv3Err(new ErrorV3(msg, 'not-customBotWithoutProxy'), 400);
     }
 
     const { slackSigningSecret, slackBotToken } = req.body;
     const requestParams = {
-      'slackbot:signingSecret': slackSigningSecret,
-      'slackbot:token': slackBotToken,
+      'slackbot:withoutProxy:signingSecret': slackSigningSecret,
+      'slackbot:withoutProxy:botToken': slackBotToken,
     };
     try {
       await updateSlackBotSettings(requestParams);
       crowi.slackIntegrationService.publishUpdatedMessage();
 
       const customBotWithoutProxySettingParams = {
-        slackSigningSecret: crowi.configManager.getConfig('crowi', 'slackbot:signingSecret'),
-        slackBotToken: crowi.configManager.getConfig('crowi', 'slackbot:token'),
+        slackSigningSecret: crowi.configManager.getConfig('crowi', 'slackbot:withoutProxy:signingSecret'),
+        slackBotToken: crowi.configManager.getConfig('crowi', 'slackbot:withoutProxy:botToken'),
       };
       return res.apiv3({ customBotWithoutProxySettingParams });
     }
@@ -438,7 +441,7 @@ module.exports = (crowi) => {
   router.put('/proxy-uri', loginRequiredStrictly, adminRequired, csrf, validator.proxyUri, apiV3FormValidator, async(req, res) => {
     const { proxyUri } = req.body;
 
-    const requestParams = { 'slackbot:proxyServerUri': proxyUri };
+    const requestParams = { 'slackbot:proxyUri': proxyUri };
 
     try {
       await updateSlackBotSettings(requestParams);
@@ -554,7 +557,7 @@ module.exports = (crowi) => {
         { new: true },
       );
 
-      const proxyUri = crowi.configManager.getConfig('crowi', 'slackbot:proxyServerUri');
+      const proxyUri = crowi.configManager.getConfig('crowi', 'slackbot:proxyUri');
       if (proxyUri != null) {
         await requestToProxyServer(
           slackAppIntegration.tokenGtoP,
@@ -592,12 +595,12 @@ module.exports = (crowi) => {
   // eslint-disable-next-line max-len
   router.post('/slack-app-integrations/:id/relation-test', loginRequiredStrictly, adminRequired, csrf, validator.relationTest, apiV3FormValidator, async(req, res) => {
     const currentBotType = crowi.configManager.getConfig('crowi', 'slackbot:currentBotType');
-    if (currentBotType === 'customBotWithoutProxy') {
+    if (currentBotType === SlackbotType.CUSTOM_WITHOUT_PROXY) {
       const msg = 'Not Proxy Type';
       return res.apiv3Err(new ErrorV3(msg, 'not-proxy-type'), 400);
     }
 
-    const proxyUri = crowi.configManager.getConfig('crowi', 'slackbot:proxyServerUri');
+    const proxyUri = crowi.configManager.getConfig('crowi', 'slackbot:proxyUri');
     if (proxyUri == null) {
       return res.apiv3Err(new ErrorV3('Proxy URL is null.', 'not-proxy-Uri'), 400);
     }
@@ -666,12 +669,12 @@ module.exports = (crowi) => {
    */
   router.post('/without-proxy/test', loginRequiredStrictly, adminRequired, csrf, validator.slackChannel, apiV3FormValidator, async(req, res) => {
     const currentBotType = crowi.configManager.getConfig('crowi', 'slackbot:currentBotType');
-    if (currentBotType !== 'customBotWithoutProxy') {
+    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:token');
+    const slackBotToken = crowi.configManager.getConfig('crowi', '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'));

+ 1 - 1
packages/app/src/server/routes/apiv3/slack-integration.js

@@ -94,7 +94,7 @@ module.exports = (crowi) => {
   }
 
   const addSigningSecretToReq = (req, res, next) => {
-    req.slackSigningSecret = configManager.getConfig('crowi', 'slackbot:signingSecret');
+    req.slackSigningSecret = configManager.getConfig('crowi', 'slackbot:withoutProxy:signingSecret');
     return next();
   };
 

+ 28 - 14
packages/app/src/server/service/config-loader.ts

@@ -444,39 +444,53 @@ const ENV_VAR_NAME_TO_CONFIG_INFO = {
     type:    ValueType.STRING,
     default: null,
   },
-  SLACK_SIGNING_SECRET: {
+  GROWI_APP_ID_FOR_GROWI_CLOUD: {
     ns:      'crowi',
-    key:     'slackbot:signingSecret',
+    key:     'app:growiAppIdForCloud',
     type:    ValueType.STRING,
     default: null,
   },
-  SLACK_BOT_TOKEN: {
+  DEFAULT_EMAIL_PUBLISHED: {
+    ns:      'crowi',
+    key:     'customize:isEmailPublishedForNewUser',
+    type:    ValueType.BOOLEAN,
+    default: true,
+  },
+  SLACKBOT_TYPE: {
     ns:      'crowi',
-    key:     'slackbot:token',
+    key:     'slackbot:currentBotType', // enum SlackbotType
     type:    ValueType.STRING,
     default: null,
   },
-  SLACK_INTEGRATION_PROXY_URI: {
+  SLACKBOT_INTEGRATION_PROXY_URI: {
     ns:      'crowi',
-    key:     'slackbot:proxyServerUri',
+    key:     'slackbot:proxyUri',
     type:    ValueType.STRING,
     default: null,
   },
-  SLACK_BOT_TYPE: {
+  SLACKBOT_WITHOUT_PROXY_SIGNING_SECRET: {
     ns:      'crowi',
-    key:     'slackbot:currentBotType', // 'officialBot' || 'customBotWithoutProxy' || 'customBotWithProxy'
+    key:     'slackbot:withoutProxy:signingSecret',
+    type:    ValueType.STRING,
+    default: null,
   },
-  GROWI_APP_ID_FOR_GROWI_CLOUD: {
+  SLACKBOT_WITHOUT_PROXY_BOT_TOKEN: {
     ns:      'crowi',
-    key:     'app:growiAppIdForCloud',
+    key:     'slackbot:withoutProxy:botToken',
     type:    ValueType.STRING,
     default: null,
   },
-  DEFAULT_EMAIL_PUBLISHED: {
+  SLACKBOT_WITH_PROXY_SALT_FOR_GTOP: {
     ns:      'crowi',
-    key:     'customize:isEmailPublishedForNewUser',
-    type:    ValueType.BOOLEAN,
-    default: true,
+    key:     'slackbot:withProxy:saltForGtoP',
+    type:    ValueType.STRING,
+    default: 'gtop',
+  },
+  SLACKBOT_WITH_PROXY_SALT_FOR_PTOG: {
+    ns:      'crowi',
+    key:     'slackbot:withProxy:saltForPtoG',
+    type:    ValueType.STRING,
+    default: 'ptog',
   },
 };
 

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

@@ -2,10 +2,11 @@ import mongoose from 'mongoose';
 
 import { IncomingWebhookSendArguments } from '@slack/webhook';
 import { ChatPostMessageArguments, WebClient } from '@slack/web-api';
-import { generateWebClient, markdownSectionBlock } from '@growi/slack';
 
+import { generateWebClient, markdownSectionBlock, SlackbotType } from '@growi/slack';
 
 import loggerFactory from '~/utils/logger';
+
 import S2sMessage from '../models/vo/s2s-message';
 
 import ConfigManager from './config-manager';
@@ -99,22 +100,22 @@ export class SlackIntegrationService implements S2sMessageHandlable {
   private isCheckTypeValid(): boolean {
     const currentBotType = this.configManager.getConfig('crowi', 'slackbot:currentBotType');
     if (currentBotType == null) {
-      throw new Error('The config \'SLACK_BOT_TYPE\'(ns: \'crowi\', key: \'slackbot:currentBotType\') must be set.');
+      throw new Error('The config \'SLACKBOT_TYPE\'(ns: \'crowi\', key: \'slackbot:currentBotType\') must be set.');
     }
 
     return true;
   }
 
   /**
-   * generate WebClient instance for 'customBotWithoutProxy' type
+   * generate WebClient instance for CUSTOM_WITHOUT_PROXY type
    */
   async generateClientForCustomBotWithoutProxy(): Promise<WebClient> {
     this.isCheckTypeValid();
 
-    const token = this.configManager.getConfig('crowi', 'slackbot:token');
+    const token = this.configManager.getConfig('crowi', 'slackbot:withoutProxy:botToken');
 
     if (token == null) {
-      throw new Error('The config \'SLACK_BOT_TOKEN\'(ns: \'crowi\', key: \'slackbot:token\') must be set.');
+      throw new Error('The config \'SLACK_BOT_TOKEN\'(ns: \'crowi\', key: \'slackbot:withoutProxy:botToken\') must be set.');
     }
 
     return generateWebClient(token);
@@ -147,7 +148,7 @@ export class SlackIntegrationService implements S2sMessageHandlable {
 
     const currentBotType = this.configManager.getConfig('crowi', 'slackbot:currentBotType');
 
-    if (currentBotType === 'customBotWithoutProxy') {
+    if (currentBotType === SlackbotType.CUSTOM_WITHOUT_PROXY) {
       return this.generateClientForCustomBotWithoutProxy();
     }
 
@@ -170,7 +171,7 @@ export class SlackIntegrationService implements S2sMessageHandlable {
     this.isCheckTypeValid();
 
     // connect to proxy
-    const proxyServerUri = this.configManager.getConfig('crowi', 'slackbot:proxyServerUri');
+    const proxyServerUri = this.configManager.getConfig('crowi', 'slackbot:proxyUri');
     const serverUri = new URL('/g2s', proxyServerUri);
     const headers = {
       'x-growi-gtop-tokens': slackAppIntegration.tokenGtoP,

+ 1 - 0
packages/slack/src/index.ts

@@ -25,6 +25,7 @@ export const defaultSupportedCommandsNameForSingleUse: string[] = [
 export * from './interfaces/growi-command';
 export * from './interfaces/request-between-growi-and-proxy';
 export * from './interfaces/request-from-slack';
+export * from './interfaces/slackbot-types';
 export * from './models/errors';
 export * from './middlewares/verify-growi-to-slack-request';
 export * from './middlewares/verify-slack-request';

+ 5 - 0
packages/slack/src/interfaces/slackbot-types.ts

@@ -0,0 +1,5 @@
+export enum SlackbotType {
+  OFFICIAL = 'officialBot',
+  CUSTOM_WITHOUT_PROXY = 'customBotWithoutProxy',
+  CUSTOM_WITH_PROXY = 'customBotWithProxy',
+}