Преглед изворни кода

Merge pull request #8780 from weseek/support/make-aws-file-uploader-type-safe

support: Make AwsFileUploader type safe
Yuki Takei пре 1 година
родитељ
комит
8fc7cc1231
1 измењених фајлова са 16 додато и 37 уклоњено
  1. 16 37
      apps/app/src/server/service/file-uploader/aws.ts

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

@@ -1,3 +1,4 @@
+import type { GetObjectCommandInput, HeadObjectCommandInput } from '@aws-sdk/client-s3';
 import {
   S3Client,
   HeadObjectCommand,
@@ -6,7 +7,6 @@ import {
   PutObjectCommand,
   DeleteObjectCommand,
   ListObjectsCommand,
-  type GetObjectCommandInput,
   ObjectCannedACL,
 } from '@aws-sdk/client-s3';
 import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
@@ -35,19 +35,7 @@ interface FileMeta {
   size: number;
 }
 
-type AwsCredential = {
-  accessKeyId: string,
-  secretAccessKey: string
-}
-type AwsConfig = {
-  credentials: AwsCredential,
-  region: string,
-  endpoint: string,
-  bucket: string,
-  forcePathStyle?: boolean
-}
-
-const isFileExists = async(s3: S3Client, params) => {
+const isFileExists = async(s3: S3Client, params: HeadObjectCommandInput) => {
   try {
     await s3.send(new HeadObjectCommand(params));
   }
@@ -60,22 +48,20 @@ const isFileExists = async(s3: S3Client, params) => {
   return true;
 };
 
-const getAwsConfig = (): AwsConfig => {
-  return {
+const getS3Bucket = (): string | undefined => {
+  return configManager.getConfig('crowi', 'aws:s3Bucket') ?? undefined; // return undefined when getConfig() returns null
+};
+
+const S3Factory = (): S3Client => {
+  return new S3Client({
     credentials: {
       accessKeyId: configManager.getConfig('crowi', 'aws:s3AccessKeyId'),
       secretAccessKey: configManager.getConfig('crowi', 'aws:s3SecretAccessKey'),
     },
     region: configManager.getConfig('crowi', 'aws:s3Region'),
     endpoint: configManager.getConfig('crowi', 'aws:s3CustomEndpoint'),
-    bucket: configManager.getConfig('crowi', 'aws:s3Bucket'),
     forcePathStyle: configManager.getConfig('crowi', 'aws:s3CustomEndpoint') != null, // s3ForcePathStyle renamed to forcePathStyle in v3
-  };
-};
-
-const S3Factory = (): S3Client => {
-  const config = getAwsConfig();
-  return new S3Client(config);
+  });
 };
 
 const getFilePathOnStorage = (attachment) => {
@@ -148,11 +134,10 @@ class AwsFileUploader extends AbstractFileUploader {
     }
 
     const s3 = S3Factory();
-    const awsConfig = getAwsConfig();
     const filePath = getFilePathOnStorage(attachment);
 
     const params = {
-      Bucket: awsConfig.bucket,
+      Bucket: getS3Bucket(),
       Key: filePath,
     };
 
@@ -191,7 +176,6 @@ class AwsFileUploader extends AbstractFileUploader {
     }
 
     const s3 = S3Factory();
-    const awsConfig = getAwsConfig();
     const filePath = getFilePathOnStorage(attachment);
     const lifetimeSecForTemporaryUrl = configManager.getConfig('crowi', 'aws:lifetimeSecForTemporaryUrl');
 
@@ -200,7 +184,7 @@ class AwsFileUploader extends AbstractFileUploader {
     const isDownload = opts?.download ?? false;
     const contentHeaders = new ContentHeaders(attachment, { inline: !isDownload });
     const params: GetObjectCommandInput = {
-      Bucket: awsConfig.bucket,
+      Bucket: getS3Bucket(),
       Key: filePath,
       ResponseContentType: contentHeaders.contentType?.value.toString(),
       ResponseContentDisposition: contentHeaders.contentDisposition?.value.toString(),
@@ -241,14 +225,13 @@ module.exports = (crowi) => {
       throw new Error('AWS is not configured.');
     }
     const s3 = S3Factory();
-    const awsConfig = getAwsConfig();
 
     const filePaths = attachments.map((attachment) => {
       return { Key: getFilePathOnStorage(attachment) };
     });
 
     const totalParams = {
-      Bucket: awsConfig.bucket,
+      Bucket: getS3Bucket(),
       Delete: { Objects: filePaths },
     };
     return s3.send(new DeleteObjectsCommand(totalParams));
@@ -259,10 +242,9 @@ module.exports = (crowi) => {
       throw new Error('AWS is not configured.');
     }
     const s3 = S3Factory();
-    const awsConfig = getAwsConfig();
 
     const params = {
-      Bucket: awsConfig.bucket,
+      Bucket: getS3Bucket(),
       Key: filePath,
     };
 
@@ -284,13 +266,12 @@ module.exports = (crowi) => {
     logger.debug(`File uploading: fileName=${attachment.fileName}`);
 
     const s3 = S3Factory();
-    const awsConfig = getAwsConfig();
 
     const filePath = getFilePathOnStorage(attachment);
     const contentHeaders = new ContentHeaders(attachment);
 
     return s3.send(new PutObjectCommand({
-      Bucket: awsConfig.bucket,
+      Bucket: getS3Bucket(),
       Key: filePath,
       Body: fileStream,
       ACL: ObjectCannedACL.public_read,
@@ -302,10 +283,9 @@ module.exports = (crowi) => {
 
   lib.saveFile = async function({ filePath, contentType, data }) {
     const s3 = S3Factory();
-    const awsConfig = getAwsConfig();
 
     return s3.send(new PutObjectCommand({
-      Bucket: awsConfig.bucket,
+      Bucket: getS3Bucket(),
       ContentType: contentType,
       Key: filePath,
       Body: data,
@@ -329,9 +309,8 @@ module.exports = (crowi) => {
 
     const files: FileMeta[] = [];
     const s3 = S3Factory();
-    const awsConfig = getAwsConfig();
     const params = {
-      Bucket: awsConfig.bucket,
+      Bucket: getS3Bucket(),
     };
     let shouldContinue = true;
     let nextMarker: string | undefined;