Skip to content
This repository was archived by the owner on Feb 21, 2023. It is now read-only.

Commit fd9bad7

Browse files
author
valflrt
committed
Edit commands encrypt and decrypt
- Implement new FileMap - Add some comments (yes yes)
1 parent 14ff3aa commit fd9bad7

File tree

2 files changed

+128
-90
lines changed

2 files changed

+128
-90
lines changed

src/commands/decrypt.ts

Lines changed: 70 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Command } from "commander";
2-
32
import fs, { existsSync } from "fs";
43
import fsAsync from "fs/promises";
54
import pathProgram from "path";
@@ -8,7 +7,6 @@ import throat from "throat";
87
import Encryption from "../Encryption";
98
import Tree from "../Tree";
109
import FileMap from "../FileMap";
11-
1210
import Logger from "../Logger";
1311
import Timer from "../Timer";
1412

@@ -85,7 +83,10 @@ export default new Command("decrypt")
8583
process.exit();
8684
}
8785

88-
// Loops through given paths and gets information about them
86+
/**
87+
* Loops through given paths (the cli arguments), runs
88+
* some checks and maps them.
89+
*/
8990
let inputItems = await Promise.all(
9091
inputPaths.map(
9192
async (
@@ -99,7 +100,8 @@ export default new Command("decrypt")
99100
// Reads current path stats
100101
let pathStats = await fsAsync.stat(inputPath);
101102

102-
let humanReadableItemType = pathStats.isFile()
103+
// Creates human addressed and readable item type
104+
let humanAddressedItemType = pathStats.isFile()
103105
? "file"
104106
: pathStats.isDirectory()
105107
? "directory"
@@ -108,7 +110,7 @@ export default new Command("decrypt")
108110
// Checks if the item exists
109111
if (!existsSync(inputPath)) {
110112
logger.error(
111-
`This ${humanReadableItemType} doesn't exist.\n(path: ${inputPath})`
113+
`This ${humanAddressedItemType} doesn't exist.\n(path: ${inputPath})`
112114
);
113115
process.exit();
114116
}
@@ -136,7 +138,7 @@ export default new Command("decrypt")
136138
} catch (e) {
137139
logger.debugOnly.error(e);
138140
logger.error(
139-
`Failed to overwrite the output ${humanReadableItemType}.\n(path: ${outputPath})`
141+
`Failed to overwrite the output ${humanAddressedItemType}.\n(path: ${outputPath})`
140142
);
141143
}
142144
} else {
@@ -153,6 +155,10 @@ export default new Command("decrypt")
153155
}
154156
}
155157

158+
/**
159+
* Returns different objects whether the item is
160+
* a directory, a file or something else
161+
*/
156162
if (pathStats.isDirectory()) {
157163
return {
158164
type: "directory",
@@ -168,7 +174,7 @@ export default new Command("decrypt")
168174
};
169175
} else {
170176
logger.warn(
171-
"An item that is neither a file nor directory was found, skipping...\n".concat(
177+
"An item that is neither a file nor directory was found, it will be skipped.\n".concat(
172178
`(path: ${inputPath})`
173179
)
174180
);
@@ -189,14 +195,12 @@ export default new Command("decrypt")
189195
let clean = async () => {
190196
try {
191197
await Promise.all(
192-
inputItems.map(
193-
throat(10, async (item) => {
194-
await fsAsync.rm(item.outputPath, {
195-
recursive: true,
196-
force: true,
197-
});
198-
})
199-
)
198+
inputItems.map(async (i) => {
199+
await fsAsync.rm(i.outputPath, {
200+
recursive: true,
201+
force: true,
202+
});
203+
})
200204
);
201205
} catch (e) {
202206
logger.debugOnly.error(e);
@@ -210,18 +214,18 @@ export default new Command("decrypt")
210214
try {
211215
let allValid = (
212216
await Promise.all(
213-
inputItems.map(async (i) => {
214-
if (i.type === "directory") {
217+
inputItems.map(async (item) => {
218+
if (item.type === "directory") {
215219
return (
216220
await Promise.all(
217-
await i.tree!.map((i) =>
221+
await item.tree!.map((i) =>
218222
encryption.validateStream(fs.createReadStream(i.path))
219223
)
220224
)
221225
).every((i) => !!i);
222226
} else {
223227
return await encryption.validateStream(
224-
fs.createReadStream(i.inputPath)
228+
fs.createReadStream(item.inputPath)
225229
);
226230
}
227231
})
@@ -251,8 +255,8 @@ export default new Command("decrypt")
251255
await Promise.all(
252256
inputItems.map(async (inputItem) => {
253257
/**
254-
* Check if the item is a directory, a file or
255-
* something else
258+
* Do something whether the item is a directory,
259+
* a file or something else
256260
*/
257261
if (inputItem.type === "directory") {
258262
// Creates base directory (typically [name of the dir to encrypt].encrypted)
@@ -264,65 +268,84 @@ export default new Command("decrypt")
264268
process.exit();
265269
}
266270

267-
// Finds file map
268-
let fileMap = (
271+
// Finds file map (the encrypted file itself)
272+
let fileMapPath = (
269273
await Promise.all(
270274
await inputItem.tree!.map(
271-
throat(20, async (item) => {
272-
let bufferedName = Buffer.from(item.name, "base64url");
273-
if (
274-
encryption.validate(bufferedName) &&
275-
encryption.decrypt(bufferedName).toString("utf8") ===
275+
throat(60, async (item) => {
276+
let itemName = Buffer.from(item.name, "base64url");
277+
/**
278+
* You might think this is not secure
279+
* because an encrypted file could also
280+
* be named "fileMap", it will be found
281+
* and used as file map, in this case
282+
* please see `../encrypt.ts` at line
283+
* 286
284+
*/
285+
return encryption.validate(itemName) &&
286+
encryption.decrypt(itemName).toString("utf8") ===
276287
"fileMap"
277-
) {
278-
let parsed = FileMap.parse(
279-
encryption
280-
.decrypt(await fsAsync.readFile(item.path))
281-
.toString("utf8")
282-
)?.items;
283-
if (!parsed) return null;
284-
else return parsed;
285-
} else return null;
288+
? item.path
289+
: undefined;
286290
})
287291
)
288292
)
289293
).find((i) => !!i);
290-
if (!fileMap) {
294+
if (!fileMapPath) {
291295
logger.error(
292296
"Couldn't decrypt because file map can't be found"
293297
);
294298
process.exit();
295299
}
296300

297301
/**
298-
* Reads file map and decrypt items depending
302+
* Creates FileMap object
303+
*/
304+
let fileMap = await FileMap.new();
305+
/**
306+
* Decrypts file map and write the result in
307+
* the temporary file map created when using
308+
* FileMap.new();
309+
*/
310+
await encryption.decryptStream(
311+
fs.createReadStream(fileMapPath),
312+
fs.createWriteStream(fileMap.tmpFilePath)
313+
);
314+
315+
/**
316+
* Parses file map and decrypts items depending
299317
* on it
300318
*/
301319
await Promise.all(
302-
fileMap.map(
303-
throat(20, async ([plain, randomized]) => {
320+
await fileMap.parseAndMap(
321+
throat(60, async ([plain, encrypted]) => {
322+
if (plain === "fileMap") return;
304323
let newPath = pathProgram.join(inputItem.outputPath, plain);
324+
/**
325+
* Creates directories if necessary
326+
*/
305327
await fsAsync.mkdir(
306328
pathProgram.resolve(pathProgram.dirname(newPath)),
307329
{
308330
recursive: true,
309331
}
310332
);
333+
/**
334+
* Decrypts item
335+
*/
311336
await encryption.decryptStream(
312337
fs.createReadStream(
313-
pathProgram.join(inputItem.inputPath, randomized)
338+
pathProgram.join(inputItem.inputPath, encrypted)
314339
),
315340
fs.createWriteStream(newPath)
316341
);
317342
})
318343
)
319344
);
320-
321-
// Removes file map
322-
await fsAsync.rm(
323-
pathProgram.join(inputItem.outputPath, "fileMap")
324-
);
325345
} else if (inputItem.type === "file") {
346+
/**
347+
* Decrypts file
348+
*/
326349
await encryption.decryptStream(
327350
fs.createReadStream(inputItem.inputPath),
328351
fs.createWriteStream(inputItem.outputPath)

0 commit comments

Comments
 (0)