diff --git a/plugins/qeta-backend/src/service/routes/attachments.ts b/plugins/qeta-backend/src/service/routes/attachments.ts index b6979deb..7f40885f 100644 --- a/plugins/qeta-backend/src/service/routes/attachments.ts +++ b/plugins/qeta-backend/src/service/routes/attachments.ts @@ -8,11 +8,8 @@ import S3StoreEngine from '../upload/s3'; import fs from 'fs'; import FileType from 'file-type'; import { File } from '../types'; -import { - S3Client, - GetObjectCommand, - GetObjectCommandOutput, -} from '@aws-sdk/client-s3'; +import { GetObjectCommand, GetObjectCommandOutput } from '@aws-sdk/client-s3'; +import { getS3Client } from '../util'; const DEFAULT_IMAGE_SIZE_LIMIT = 2500000; const DEFAULT_MIME_TYPES = [ @@ -110,24 +107,10 @@ export const attachmentsRoutes = (router: Router, options: RouterOptions) => { imageBuffer = attachment.binaryImage; } else if (attachment.locationType === 's3') { const bucket = config.getOptionalString('qeta.storage.bucket'); - const accessKeyId = config.getOptionalString('qeta.storage.accessKeyId'); - const secretAccessKey = config.getOptionalString( - 'qeta.storage.secretAccessKey', - ); - const region = config.getOptionalString('qeta.storage.region'); if (!bucket) { throw new Error('Bucket name is required for S3 storage'); } - const s3 = - accessKeyId && secretAccessKey && region - ? new S3Client({ - credentials: { - accessKeyId, - secretAccessKey, - }, - region, - }) - : new S3Client(); + const s3 = getS3Client(config); const object: GetObjectCommandOutput = await s3.send( new GetObjectCommand({ Bucket: bucket, diff --git a/plugins/qeta-backend/src/service/upload/s3.ts b/plugins/qeta-backend/src/service/upload/s3.ts index 520890c6..b6a13bb1 100644 --- a/plugins/qeta-backend/src/service/upload/s3.ts +++ b/plugins/qeta-backend/src/service/upload/s3.ts @@ -4,7 +4,8 @@ import { Config } from '@backstage/config'; import { QetaStore } from '../../database/QetaStore'; import { Attachment } from '@drodil/backstage-plugin-qeta-common'; import { File } from '../types'; -import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'; +import { PutObjectCommand } from '@aws-sdk/client-s3'; +import { getS3Client } from '../util'; type Options = { config: Config; @@ -19,9 +20,6 @@ class S3StoreEngine { folder: string; bucket?: string; - accessKeyId?: string; - secretAccessKey?: string; - region?: string; constructor(opts: Options) { this.config = opts.config; @@ -29,31 +27,11 @@ class S3StoreEngine { this.backendBaseUrl = this.config.getString('backend.baseUrl'); this.qetaUrl = `${this.backendBaseUrl}/api/qeta/attachments`; this.bucket = this.config.getOptionalString('qeta.storage.bucket'); - this.accessKeyId = this.config.getOptionalString( - 'qeta.storage.accessKeyId', - ); - this.secretAccessKey = this.config.getOptionalString( - 'qeta.storage.secretAccessKey', - ); this.folder = this.config.getOptionalString('qeta.storage.folder') || '/backstage-qeta-images'; - this.region = this.config.getOptionalString('qeta.storage.region'); } - newClient = (): S3Client => { - if (this.accessKeyId && this.secretAccessKey && this.region) { - return new S3Client({ - credentials: { - accessKeyId: this.accessKeyId, - secretAccessKey: this.secretAccessKey, - }, - region: this.region, - }); - } - return new S3Client({}); - }; - handleFile = async (file: File): Promise => { if (!this.bucket) { throw new Error('Bucket name is required for S3 storage'); @@ -62,7 +40,7 @@ class S3StoreEngine { const filename = `image-${imageUuid}-${Date.now()}.${file.ext}`; const newPath = `${this.folder}/${filename}`; const imageURI = `${this.qetaUrl}/${imageUuid}`; - const client = this.newClient(); + const client = getS3Client(this.config); const uploadArgs = { Bucket: this.bucket, Key: newPath, diff --git a/plugins/qeta-backend/src/service/util.ts b/plugins/qeta-backend/src/service/util.ts index 3484e6d6..3aa9c588 100644 --- a/plugins/qeta-backend/src/service/util.ts +++ b/plugins/qeta-backend/src/service/util.ts @@ -8,6 +8,8 @@ import { } from '@backstage/plugin-permission-common'; import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node'; import { MaybeAnswer, MaybeQuestion } from '../database/QetaStore'; +import { Config } from '@backstage/config'; +import { S3Client } from '@aws-sdk/client-s3'; export const getUsername = async ( req: Request, @@ -149,3 +151,21 @@ export const stringDateTime = (dayString: string) => { return formattedDate; }; + +export const getS3Client = (config: Config) => { + const accessKeyId = config.getOptionalString('qeta.storage.accessKeyId'); + const secretAccessKey = config.getOptionalString( + 'qeta.storage.secretAccessKey', + ); + const region = config.getOptionalString('qeta.storage.region'); + if (accessKeyId && secretAccessKey) { + return new S3Client({ + credentials: { + accessKeyId, + secretAccessKey, + }, + region, + }); + } + return new S3Client({ region }); +};