@@ -3,7 +3,6 @@ import fs from "fs"
3
3
import zlib from "zlib"
4
4
import env from "../environment"
5
5
import { join } from "path"
6
- import { PassThrough , Readable } from "stream"
7
6
8
7
const ALGO = "aes-256-ctr"
9
8
const SEPARATOR = "-"
@@ -80,103 +79,24 @@ export async function encryptFile(
80
79
const inputFile = fs . createReadStream ( filePath )
81
80
const outputFile = fs . createWriteStream ( join ( dir , outputFileName ) )
82
81
83
- encryptStream ( inputFile , secret ) . pipe ( outputFile )
84
-
85
- return new Promise < { filename : string ; dir : string } > ( ( resolve , reject ) => {
86
- outputFile . on ( "finish" , ( ) => {
87
- resolve ( {
88
- filename : outputFileName ,
89
- dir,
90
- } )
91
- } )
92
- const cleanupReject = ( error : Error ) => {
93
- inputFile . close ( )
94
- outputFile . close ( )
95
- reject ( error )
96
- }
97
- outputFile . on ( "error" , cleanupReject )
98
- inputFile . on ( "error" , cleanupReject )
99
- } )
100
- }
101
-
102
- export function encryptStream ( inputStream : Readable , secret : string ) : Readable {
103
82
const salt = crypto . randomBytes ( SALT_LENGTH )
104
83
const iv = crypto . randomBytes ( IV_LENGTH )
105
84
const stretched = stretchString ( secret , salt )
106
85
const cipher = crypto . createCipheriv ( ALGO , stretched , iv )
107
- const gzip = zlib . createGzip ( )
108
-
109
- const outputStream = new PassThrough ( )
110
- outputStream . write ( salt )
111
- outputStream . write ( iv )
112
-
113
- // Set up error propagation
114
- inputStream . on ( "error" , err => {
115
- gzip . destroy ( err )
116
- if ( ! outputStream . destroyed ) {
117
- outputStream . destroy ( err )
118
- }
119
- } )
120
- gzip . on ( "error" , err => {
121
- cipher . destroy ( err )
122
- if ( ! outputStream . destroyed ) {
123
- outputStream . destroy ( err )
124
- }
125
- } )
126
- cipher . on ( "error" , err => {
127
- if ( ! outputStream . destroyed ) {
128
- outputStream . destroy ( err )
129
- }
130
- } )
131
86
132
- inputStream . pipe ( gzip ) . pipe ( cipher ) . pipe ( outputStream )
87
+ outputFile . write ( salt )
88
+ outputFile . write ( iv )
133
89
134
- return outputStream
135
- }
90
+ inputFile . pipe ( zlib . createGzip ( ) ) . pipe ( cipher ) . pipe ( outputFile )
136
91
137
- export async function decryptStream (
138
- inputStream : Readable ,
139
- secret : string
140
- ) : Promise < Readable > {
141
- const outputStream = new PassThrough ( )
142
-
143
- let decipher : crypto . Decipher | null = null
144
- let gunzip : zlib . Gunzip | null = null
145
- let firstChunk = true
146
-
147
- inputStream . on ( "data" , chunk => {
148
- if ( firstChunk ) {
149
- firstChunk = false
150
- const salt = chunk . slice ( 0 , SALT_LENGTH )
151
- const iv = chunk . slice ( SALT_LENGTH , SALT_LENGTH + IV_LENGTH )
152
- chunk = chunk . slice ( SALT_LENGTH + IV_LENGTH )
153
-
154
- const stretched = stretchString ( secret , salt )
155
- decipher = crypto . createDecipheriv ( ALGO , stretched , iv )
156
- gunzip = zlib . createGunzip ( )
157
-
158
- inputStream . on ( "error" , err => {
159
- decipher ! . destroy ( err )
160
- } )
161
- decipher . on ( "error" , err => {
162
- gunzip ! . destroy ( err )
163
- } )
164
- gunzip . on ( "error" , err => {
165
- outputStream . destroy ( err )
92
+ return new Promise < { filename : string ; dir : string } > ( r => {
93
+ outputFile . on ( "finish" , ( ) => {
94
+ r ( {
95
+ filename : outputFileName ,
96
+ dir,
166
97
} )
167
-
168
- decipher . pipe ( gunzip ) . pipe ( outputStream )
169
- }
170
-
171
- decipher ! . write ( chunk )
172
- } )
173
-
174
- inputStream . on ( "end" , ( ) => {
175
- decipher ?. end ( )
176
- gunzip ?. end ( )
98
+ } )
177
99
} )
178
-
179
- return outputStream
180
100
}
181
101
182
102
async function getSaltAndIV ( path : string ) {
0 commit comments