3434import com .flowcrypt .email .database .dao .source .AccountDao ;
3535import com .flowcrypt .email .database .dao .source .AccountDaoSource ;
3636import com .flowcrypt .email .database .dao .source .imap .ImapLabelsDaoSource ;
37+ import com .flowcrypt .email .js .Js ;
38+ import com .flowcrypt .email .js .PgpDecrypted ;
39+ import com .flowcrypt .email .security .SecurityStorageConnector ;
3740import com .flowcrypt .email .util .GeneralUtil ;
3841import com .sun .mail .imap .IMAPFolder ;
3942
4043import org .apache .commons .io .FileUtils ;
44+ import org .apache .commons .io .FilenameUtils ;
4145import org .apache .commons .io .IOUtils ;
4246
4347import java .io .File ;
48+ import java .io .FileInputStream ;
4449import java .io .IOException ;
4550import java .io .InputStream ;
4651import java .io .OutputStream ;
@@ -470,10 +475,9 @@ public void run() {
470475 attachmentInfo .getId ());
471476
472477 if (attachment != null ) {
473- InputStream input = attachment .getInputStream ();
474- OutputStream output = FileUtils .openOutputStream (attachmentFile );
478+ InputStream inputStream = attachment .getInputStream ();
475479
476- try {
480+ try ( OutputStream outputStream = FileUtils . openOutputStream ( attachmentFile )) {
477481 byte [] buffer = new byte [DEFAULT_BUFFER_SIZE ];
478482 double count = 0 ;
479483 double size = attachmentInfo .getEncodedSize ();
@@ -483,9 +487,9 @@ public void run() {
483487 long startTime , elapsedTime ;
484488 long lastUpdateTime = startTime = System .currentTimeMillis ();
485489 updateProgress (currentPercentage , 0 );
486- while (IOUtils .EOF != (numberOfReadBytes = input .read (buffer ))) {
490+ while (IOUtils .EOF != (numberOfReadBytes = inputStream .read (buffer ))) {
487491 if (!Thread .currentThread ().isInterrupted ()) {
488- output .write (buffer , 0 , numberOfReadBytes );
492+ outputStream .write (buffer , 0 , numberOfReadBytes );
489493 count += numberOfReadBytes ;
490494 currentPercentage = (int ) ((count / size ) * 100f );
491495 if (currentPercentage - lastPercentage >= 1
@@ -505,15 +509,15 @@ public void run() {
505509 if (!Thread .currentThread ().isInterrupted ()) {
506510 updateProgress (100 , 0 );
507511 }
508-
509- output .close ();
510512 } finally {
511- IOUtils .closeQuietly (output );
512513 if (Thread .currentThread ().isInterrupted ()) {
513514 removeNotCompleteDownloadFile (attachmentFile );
514515 }
515516 }
516517
518+ attachmentFile = decryptFileIfNeed (context , attachmentFile );
519+ attachmentInfo .setName (attachmentFile .getName ());
520+
517521 if (!Thread .currentThread ().isInterrupted ()) {
518522 if (onDownloadAttachmentListener != null ) {
519523 onDownloadAttachmentListener .onAttachmentSuccessDownloaded (startId , attachmentInfo ,
@@ -538,6 +542,52 @@ public void setOnDownloadAttachmentListener(OnDownloadAttachmentListener onDownl
538542 this .onDownloadAttachmentListener = onDownloadAttachmentListener ;
539543 }
540544
545+ /**
546+ * Do decryption of the downloaded file if it need.
547+ *
548+ * @param context Interface to global information about an application environment;
549+ * @param file The downloaded file which can be encrypted.
550+ * @return The decrypted or the original file.
551+ */
552+ private File decryptFileIfNeed (Context context , File file ) throws IOException {
553+ if (file == null ) {
554+ return null ;
555+ }
556+
557+ if (!"pgp" .equalsIgnoreCase (FilenameUtils .getExtension (file .getName ()))) {
558+ return file ;
559+ }
560+
561+ try (InputStream inputStream = new FileInputStream (file )) {
562+ PgpDecrypted pgpDecrypted = new Js (context , new SecurityStorageConnector (context ))
563+ .crypto_message_decrypt (IOUtils .toByteArray (inputStream ));
564+ byte [] decryptedBytes = pgpDecrypted .getBytes ();
565+
566+ File decryptedFile = new File (file .getParent (),
567+ file .getName ().substring (0 , file .getName ().lastIndexOf ("." )));
568+
569+ boolean isInnerExceptionHappened = false ;
570+
571+ try (OutputStream outputStream = FileUtils .openOutputStream (decryptedFile )) {
572+ IOUtils .write (decryptedBytes , outputStream );
573+ return decryptedFile ;
574+ } catch (IOException e ) {
575+ if (!decryptedFile .delete ()) {
576+ Log .d (TAG , "Cannot delete file: " + file );
577+ }
578+
579+ isInnerExceptionHappened = true ;
580+ throw e ;
581+ } finally {
582+ if (!isInnerExceptionHappened ) {
583+ if (!file .delete ()) {
584+ Log .d (TAG , "Cannot delete file: " + file );
585+ }
586+ }
587+ }
588+ }
589+ }
590+
541591 /**
542592 * Remove the file which not downloaded fully.
543593 *
0 commit comments