Browse Source

fix(slack): normalize proxyUri to undefined for custom bot without proxy mode

When proxyUri is not configured, configManager.getConfig() may return null
from the DB, which proxyUriForCurrentType returns as-is. The previous code
then converted undefined to null via nullish coalescing, and generateRespondUtil
received null instead of undefined, causing urljoin(null) to throw TypeError.

Fix by:
- Narrowing slackbot:proxyUri config type to NonBlankString | undefined
- Using toNonBlankStringOrUndefined() in proxyUriForCurrentType to normalize
  any falsy value (null, empty string) to undefined at the service layer
- Removing the erroneous nullish coalescing in getRespondUtil

Fixes #11031

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Yuki Takei 1 day ago
parent
commit
6cbb94ee15

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

@@ -280,7 +280,7 @@ module.exports = (crowi) => {
   };
   };
 
 
   function getRespondUtil(responseUrl) {
   function getRespondUtil(responseUrl) {
-    const proxyUri = slackIntegrationService.proxyUriForCurrentType ?? null; // can be null
+    const proxyUri = slackIntegrationService.proxyUriForCurrentType;
 
 
     const appSiteUrl = growiInfoService.getSiteUrl();
     const appSiteUrl = growiInfoService.getSiteUrl();
     if (appSiteUrl == null || appSiteUrl === '') {
     if (appSiteUrl == null || appSiteUrl === '') {

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

@@ -1115,7 +1115,7 @@ export const CONFIG_DEFINITIONS = {
     envVarName: 'SLACKBOT_TYPE',
     envVarName: 'SLACKBOT_TYPE',
     defaultValue: undefined,
     defaultValue: undefined,
   }),
   }),
-  'slackbot:proxyUri': defineConfig<string | undefined>({
+  'slackbot:proxyUri': defineConfig<NonBlankString | undefined>({
     envVarName: 'SLACKBOT_INTEGRATION_PROXY_URI',
     envVarName: 'SLACKBOT_INTEGRATION_PROXY_URI',
     defaultValue: undefined,
     defaultValue: undefined,
   }),
   }),

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

@@ -1,3 +1,4 @@
+import { toNonBlankStringOrUndefined } from '@growi/core/dist/interfaces';
 import {
 import {
   type GrowiBotEvent,
   type GrowiBotEvent,
   type GrowiCommand,
   type GrowiCommand,
@@ -132,18 +133,14 @@ export class SlackIntegrationService implements S2sMessageHandlable {
 
 
     // TODO assert currentBotType is not null and CUSTOM_WITHOUT_PROXY
     // TODO assert currentBotType is not null and CUSTOM_WITHOUT_PROXY
 
 
-    let proxyUri: string | undefined;
-
     switch (currentBotType) {
     switch (currentBotType) {
       case SlackbotType.OFFICIAL:
       case SlackbotType.OFFICIAL:
-        proxyUri = OFFICIAL_SLACKBOT_PROXY_URI;
-        break;
+        return OFFICIAL_SLACKBOT_PROXY_URI;
       default:
       default:
-        proxyUri = configManager.getConfig('slackbot:proxyUri');
-        break;
+        return toNonBlankStringOrUndefined(
+          configManager.getConfig('slackbot:proxyUri'),
+        );
     }
     }
-
-    return proxyUri;
   }
   }
 
 
   /**
   /**