2
0
Эх сурвалжийг харах

update aws s3 configuration handling

Yuki Takei 10 сар өмнө
parent
commit
1e6bf9dd02

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

@@ -1,4 +1,6 @@
-import { ConfigSource } from '@growi/core/dist/interfaces';
+import {
+  ConfigSource, toNonBlankString, toNonBlankStringOrUndefined,
+} from '@growi/core/dist/interfaces';
 import { ErrorV3 } from '@growi/core/dist/models';
 import { body } from 'express-validator';
 
@@ -900,10 +902,16 @@ module.exports = (crowi) => {
     }
 
     if (fileUploadType === 'aws') {
-      requestParams['aws:s3Region'] = req.body.s3Region;
-      requestParams['aws:s3CustomEndpoint'] = req.body.s3CustomEndpoint;
-      requestParams['aws:s3Bucket'] = req.body.s3Bucket;
-      requestParams['aws:s3AccessKeyId'] = req.body.s3AccessKeyId;
+      try {
+        requestParams['aws:s3Region'] = toNonBlankString(req.body.s3Region);
+        requestParams['aws:s3Bucket'] = toNonBlankString(req.body.s3Bucket);
+      }
+      catch (err) {
+        logger.warn('AWS S3 region or bucket name is not updated because of invalid value', err);
+      }
+
+      requestParams['aws:s3CustomEndpoint'] = toNonBlankStringOrUndefined(req.body.s3CustomEndpoint);
+      requestParams['aws:s3AccessKeyId'] = toNonBlankStringOrUndefined(req.body.s3AccessKeyId);
       requestParams['aws:referenceFileWithRelayMode'] = req.body.s3ReferenceFileWithRelayMode;
     }
 

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

@@ -1,6 +1,9 @@
 import { GrowiDeploymentType, GrowiServiceType } from '@growi/core/dist/consts';
-import type { ConfigDefinition, Lang } from '@growi/core/dist/interfaces';
-import { defineConfig } from '@growi/core/dist/interfaces';
+import type { ConfigDefinition, Lang, NonBlankString } from '@growi/core/dist/interfaces';
+import {
+  toNonBlankString,
+  defineConfig,
+} from '@growi/core/dist/interfaces';
 import type OpenAI from 'openai';
 
 import { ActionGroupSize } from '~/interfaces/activity';
@@ -819,19 +822,20 @@ export const CONFIG_DEFINITIONS = {
     envVarName: 'S3_OBJECT_ACL',
     defaultValue: undefined,
   }),
-  'aws:s3Bucket': defineConfig<string>({
-    defaultValue: 'growi',
+  'aws:s3Bucket': defineConfig<NonBlankString>({
+    defaultValue: toNonBlankString('growi'),
   }),
-  'aws:s3Region': defineConfig<string>({
-    defaultValue: 'ap-northeast-1',
+  'aws:s3Region': defineConfig<NonBlankString>({
+    defaultValue: toNonBlankString('ap-northeast-1'),
   }),
-  'aws:s3AccessKeyId': defineConfig<string | undefined>({
+  'aws:s3AccessKeyId': defineConfig<NonBlankString | undefined>({
     defaultValue: undefined,
   }),
-  'aws:s3SecretAccessKey': defineConfig<string | undefined>({
+  'aws:s3SecretAccessKey': defineConfig<NonBlankString | undefined>({
     defaultValue: undefined,
+    isSecret: true,
   }),
-  'aws:s3CustomEndpoint': defineConfig<string | undefined>({
+  'aws:s3CustomEndpoint': defineConfig<NonBlankString | undefined>({
     defaultValue: undefined,
   }),
 

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

@@ -13,6 +13,8 @@ import {
   AbortMultipartUploadCommand,
 } from '@aws-sdk/client-s3';
 import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
+import type { NonBlankString } from '@growi/core/dist/interfaces';
+import { toNonBlankStringOrUndefined } from '@growi/core/dist/interfaces';
 import urljoin from 'url-join';
 
 import type Crowi from '~/server/crowi';
@@ -79,14 +81,15 @@ const getS3PutObjectCannedAcl = (): ObjectCannedACL | undefined => {
   return undefined;
 };
 
-const getS3Bucket = (): string | undefined => {
-  return configManager.getConfig('aws:s3Bucket') ?? undefined; // return undefined when getConfig() returns null
+const getS3Bucket = (): NonBlankString | undefined => {
+  return toNonBlankStringOrUndefined(configManager.getConfig('aws:s3Bucket')); // Blank strings may remain in the DB, so convert with toNonBlankStringOrUndefined for safety
 };
 
 const S3Factory = (): S3Client => {
   const accessKeyId = configManager.getConfig('aws:s3AccessKeyId');
   const secretAccessKey = configManager.getConfig('aws:s3SecretAccessKey');
-  const s3CustomEndpoint = configManager.getConfig('aws:s3CustomEndpoint') || undefined;
+  const s3Region = toNonBlankStringOrUndefined(configManager.getConfig('aws:s3Region')); // Blank strings may remain in the DB, so convert with toNonBlankStringOrUndefined for safety
+  const s3CustomEndpoint = toNonBlankStringOrUndefined(configManager.getConfig('aws:s3CustomEndpoint'));
 
   return new S3Client({
     credentials: accessKeyId != null && secretAccessKey != null
@@ -95,9 +98,9 @@ const S3Factory = (): S3Client => {
         secretAccessKey,
       }
       : undefined,
-    region: configManager.getConfig('aws:s3Region'),
+    region: s3Region,
     endpoint: s3CustomEndpoint,
-    forcePathStyle: !!s3CustomEndpoint, // s3ForcePathStyle renamed to forcePathStyle in v3
+    forcePathStyle: s3CustomEndpoint != null, // s3ForcePathStyle renamed to forcePathStyle in v3
   });
 };