1010
1111const { SlashCommandBuilder, EmbedBuilder, AttachmentBuilder } = require ( 'discord.js' ) ;
1212const axios = require ( 'axios' ) ;
13- const { validateUrlNotInternal } = require ( '../utils/ssrf' ) ;
13+ const { validateUrlNotInternal, getSafeAxiosConfig } = require ( '../utils/ssrf' ) ;
1414const { isValidUrl } = require ( '../utils/validation' ) ;
1515const fs = require ( 'fs' ) ;
1616const path = require ( 'path' ) ;
@@ -21,14 +21,24 @@ const { URL } = require('url');
2121const { RekognitionClient, DetectLabelsCommand, DetectTextCommand,
2222 DetectFacesCommand, DetectModerationLabelsCommand,
2323 RecognizeCelebritiesCommand, CompareFacesCommand } = require ( '@aws-sdk/client-rekognition' ) ;
24- // Initialize the AWS Rekognition client (v3)
25- const rekognitionClient = new RekognitionClient ( {
26- region : process . env . AWS_REGION || 'us-east-1' ,
27- credentials : {
28- accessKeyId : process . env . AWS_ACCESS_KEY_ID ,
29- secretAccessKey : process . env . AWS_SECRET_ACCESS_KEY
24+ // Lazy-initialized AWS Rekognition client (v3)
25+ let _rekognitionClient = null ;
26+
27+ function getRekognitionClient ( ) {
28+ if ( ! _rekognitionClient ) {
29+ if ( ! process . env . AWS_ACCESS_KEY_ID || ! process . env . AWS_SECRET_ACCESS_KEY ) {
30+ throw new Error ( 'AWS credentials not configured. Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.' ) ;
31+ }
32+ _rekognitionClient = new RekognitionClient ( {
33+ region : process . env . AWS_REGION || 'us-east-1' ,
34+ credentials : {
35+ accessKeyId : process . env . AWS_ACCESS_KEY_ID ,
36+ secretAccessKey : process . env . AWS_SECRET_ACCESS_KEY
37+ }
38+ } ) ;
3039 }
31- } ) ;
40+ return _rekognitionClient ;
41+ }
3242
3343module . exports = {
3444 data : new SlashCommandBuilder ( )
@@ -194,9 +204,10 @@ async function handleAnalyze(interaction, tempDir) {
194204
195205 try {
196206 // Download the attachment
197- const response = await axios . get ( uploadedImage . url , {
207+ const response = await axios . get ( uploadedImage . url , {
198208 responseType : 'arraybuffer' ,
199- timeout : 10000 // 10 second timeout
209+ timeout : 10000 , // 10 second timeout
210+ ...getSafeAxiosConfig ( )
200211 } ) ;
201212
202213 imageBuffer = Buffer . from ( response . data ) ;
@@ -439,9 +450,10 @@ async function handleCompare(interaction, tempDir) {
439450
440451 try {
441452 // Download the attachment
442- const response = await axios . get ( sourceAttachment . url , {
453+ const response = await axios . get ( sourceAttachment . url , {
443454 responseType : 'arraybuffer' ,
444- timeout : 10000
455+ timeout : 10000 ,
456+ ...getSafeAxiosConfig ( )
445457 } ) ;
446458
447459 sourceImageBuffer = Buffer . from ( response . data ) ;
@@ -495,9 +507,10 @@ async function handleCompare(interaction, tempDir) {
495507
496508 try {
497509 // Download the attachment
498- const response = await axios . get ( targetAttachment . url , {
510+ const response = await axios . get ( targetAttachment . url , {
499511 responseType : 'arraybuffer' ,
500- timeout : 10000
512+ timeout : 10000 ,
513+ ...getSafeAxiosConfig ( )
501514 } ) ;
502515
503516 targetImageBuffer = Buffer . from ( response . data ) ;
@@ -651,9 +664,10 @@ async function downloadImage(url, tempDir, prefix = '') {
651664 const filePath = path . join ( tempDir , fileName ) ;
652665
653666 // Download the image
654- const response = await axios . get ( url , {
667+ const response = await axios . get ( url , {
655668 responseType : 'arraybuffer' ,
656- timeout : 10000 // 10 second timeout
669+ timeout : 10000 , // 10 second timeout
670+ ...getSafeAxiosConfig ( )
657671 } ) ;
658672
659673 // Check if the response is an image
@@ -720,7 +734,7 @@ async function detectLabels(imageBuffer) {
720734 } ;
721735
722736 const command = new DetectLabelsCommand ( params ) ;
723- const response = await rekognitionClient . send ( command ) ;
737+ const response = await getRekognitionClient ( ) . send ( command ) ;
724738 return response ;
725739}
726740
@@ -737,7 +751,7 @@ async function detectText(imageBuffer) {
737751 } ;
738752
739753 const command = new DetectTextCommand ( params ) ;
740- const response = await rekognitionClient . send ( command ) ;
754+ const response = await getRekognitionClient ( ) . send ( command ) ;
741755 return response ;
742756}
743757
@@ -755,7 +769,7 @@ async function detectFaces(imageBuffer) {
755769 } ;
756770
757771 const command = new DetectFacesCommand ( params ) ;
758- const response = await rekognitionClient . send ( command ) ;
772+ const response = await getRekognitionClient ( ) . send ( command ) ;
759773 return response ;
760774}
761775
@@ -773,7 +787,7 @@ async function detectModerationLabels(imageBuffer) {
773787 } ;
774788
775789 const command = new DetectModerationLabelsCommand ( params ) ;
776- const response = await rekognitionClient . send ( command ) ;
790+ const response = await getRekognitionClient ( ) . send ( command ) ;
777791 return response ;
778792}
779793
@@ -790,7 +804,7 @@ async function recognizeCelebrities(imageBuffer) {
790804 } ;
791805
792806 const command = new RecognizeCelebritiesCommand ( params ) ;
793- const response = await rekognitionClient . send ( command ) ;
807+ const response = await getRekognitionClient ( ) . send ( command ) ;
794808 return response ;
795809}
796810
@@ -813,6 +827,6 @@ async function compareFaces(sourceImageBuffer, targetImageBuffer, similarityThre
813827 } ;
814828
815829 const command = new CompareFacesCommand ( params ) ;
816- const response = await rekognitionClient . send ( command ) ;
830+ const response = await getRekognitionClient ( ) . send ( command ) ;
817831 return response ;
818832}
0 commit comments