Skip to content
This repository was archived by the owner on Oct 28, 2019. It is now read-only.

Commit ca4c352

Browse files
authored
Merge pull request #10 from oganexon/develop
1.1.1
2 parents 91f4c63 + 5b42f80 commit ca4c352

File tree

8 files changed

+93
-25
lines changed

8 files changed

+93
-25
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414

1515
## [Unreleased]
1616

17+
## [1.1.1] - 2019-08-20
18+
19+
### Added
20+
- Comment on every file.
21+
- Error recap at the end of the process.
22+
1723
## [1.1.0] - 2019-08-19
1824

1925
### Fixed

bin/cli/check.js

+35-4
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,35 @@ const inquirer = require('inquirer')
44
const chalk = require('chalk')
55
const log = require('./log')
66
const srm = require('../../')
7-
const { methods } = require('../../lib/methods')
7+
const { methods, eventEmitter } = require('../../lib/methods')
88

99
function check (argv, { method, retries, force, globbing }) {
1010
let paths = []
11+
// Search for files if globbing is enabled
1112
if (globbing) {
1213
for (let i = 0; i < argv.length; i++) {
14+
// If relative path, transform to absolute
1315
if (!path.isAbsolute(argv[i])) {
1416
argv[i] = path.join(process.cwd(), argv[i])
1517
}
18+
19+
// If on windows, transform backslashes in forwardslashes
1620
if (path.sep !== '/') {
1721
argv[i] = argv[i].split(path.sep).join('/')
1822
}
23+
24+
// Search for files
1925
paths = paths.concat(glob.sync(argv[i]))
2026
}
2127
} else paths = argv
2228
if (paths.length === 0) console.log(chalk.bold.yellow('No such file or directory.'))
29+
30+
// if there are files then continue
2331
else {
2432
console.log(chalk.bold.yellow('Method: ' + methods[method].name + '\n'))
2533
if (force) remove(paths, method, retries)
34+
35+
// Ask for confirmation
2636
else {
2737
inquirer.prompt([
2838
{
@@ -44,15 +54,36 @@ function check (argv, { method, retries, force, globbing }) {
4454
}
4555
}
4656

57+
let errorsRecord = {}
58+
59+
eventEmitter.on('error', (file, err) => {
60+
errorsRecord[err] = errorsRecord[err] || []
61+
errorsRecord[err].push(file)
62+
})
63+
4764
function remove (paths, methodID, retries) {
65+
let progress = 0
4866
for (let i = paths.length - 1; i >= 0; i--) {
67+
// Record time
4968
const start = process.hrtime()
50-
srm(paths[i], { method: methodID, maxBusyTries: retries })
51-
.then((path) => log.info(chalk.cyan(path) + chalk.cyan.bold(` deleted in ${duration(start)}.`)))
52-
.catch((err) => log.error(chalk.red.bold('Deletion of ') + chalk.red(paths[i]) + chalk.red.bold(` failed in ${duration(start)}:\n`) + chalk.red(err)))
69+
70+
srm(paths[i], { method: methodID, maxBusyTries: retries }, (err, path) => {
71+
if (err) log.error(chalk.red.bold('Deletion of ') + chalk.red(paths[i]) + chalk.red.bold(` failed in ${duration(start)}:\n`) + chalk.red(err))
72+
else log.info(chalk.cyan(path) + chalk.cyan.bold(` deleted in ${duration(start)}.`))
73+
progress++
74+
if (progress === paths.length) {
75+
if (Object.keys(errorsRecord).length !== 0) {
76+
log.info(chalk.cyan('Process ended with errors:\n'))
77+
for (let err in errorsRecord) {
78+
log(chalk.cyan.bold(err) + chalk.cyan('\n ' + errorsRecord[err].reduce((accumulator, currentValue) => `${accumulator}\n ${currentValue}`)))
79+
}
80+
}
81+
}
82+
})
5383
}
5484
}
5585

86+
// Time taken
5687
function duration (start) {
5788
const diff = process.hrtime(start)
5889
return diff[0] > 0

bin/cli/command.js

+14-7
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,18 @@ const check = require('./check')
55
const table = require('./table')
66
const { methods } = require('../../lib/methods')
77

8+
// List of valid methods IDs
89
const validIDs = Array.from(Object.keys(methods))
910

11+
// Parse the input
12+
class SecureRmCommand extends Command {
13+
async run () {
14+
const { flags, argv } = this.parse(SecureRmCommand)
15+
check(argv, flags)
16+
}
17+
}
18+
19+
// Custom flag
1020
flags.custom = (opts = {}, action) => {
1121
return Parser.flags.boolean(Object.assign(
1222
opts, {
@@ -17,18 +27,13 @@ flags.custom = (opts = {}, action) => {
1727
}))
1828
}
1929

20-
class SecureRmCommand extends Command {
21-
async run () {
22-
const { flags, argv } = this.parse(SecureRmCommand)
23-
check(argv, flags)
24-
}
25-
}
26-
30+
// CLI description
2731
SecureRmCommand.description = `CLI help:
2832
Completely erases files by making recovery impossible.
2933
For extra documentation, go to https://www.npmjs.com/package/secure-rm
3034
`
3135

36+
// CLI flags
3237
SecureRmCommand.flags = {
3338
// add --version flag to show CLI version
3439
version: flags.version({ char: 'v' }),
@@ -60,8 +65,10 @@ SecureRmCommand.flags = {
6065
table: flags.custom({ char: 't', description: 'show the methods table' }, table)
6166
}
6267

68+
// CLI args
6369
SecureRmCommand.args = [{ name: 'path', required: true }]
6470

71+
// Multiple args allowed
6572
SecureRmCommand.strict = false
6673

6774
module.exports = SecureRmCommand

bin/cli/table.js

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ const chalk = require('chalk')
22
const Table = require('tty-table')
33
const { methods } = require('../../lib/methods')
44

5+
// Draw the methods table
6+
57
const header = [
68
{
79
value: 'Id',

lib/methods.js

+15-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const { write, eventEmitter } = require('./write')
22

3-
function logError (err, file) {
3+
// Emit event with better message error
4+
function eventError (err, file) {
45
if (err) {
56
switch (err.code) {
67
case 'EMFILE':
@@ -24,6 +25,7 @@ function logError (err, file) {
2425
}
2526
}
2627

28+
// Object listing every methods
2729
const methods = {
2830
'randomData': {
2931
name: 'Pseudorandom data',
@@ -37,7 +39,7 @@ Your data is overwritten with cryptographically strong pseudo-random data. (The
3739
.then(({ file }) => write.unlink(file))
3840
.then(() => callback())
3941
.catch((err) => {
40-
logError(err, file)
42+
eventError(err, file)
4143
callback(err)
4244
})
4345
}
@@ -52,7 +54,7 @@ Your data is overwritten with cryptographically strong pseudo-random data. (The
5254
.then(({ file }) => write.unlink(file))
5355
.then(() => callback())
5456
.catch((err) => {
55-
logError(err, file)
57+
eventError(err, file)
5658
callback(err)
5759
})
5860
}
@@ -67,7 +69,7 @@ Your data is overwritten with cryptographically strong pseudo-random data. (The
6769
.then(({ file }) => write.unlink(file))
6870
.then(() => callback())
6971
.catch((err) => {
70-
logError(err, file)
72+
eventError(err, file)
7173
callback(err)
7274
})
7375
}
@@ -82,7 +84,7 @@ Your data is overwritten with cryptographically strong pseudo-random data. (The
8284
.then(({ file }) => write.unlink(file))
8385
.then(() => callback())
8486
.catch((err) => {
85-
logError(err, file)
87+
eventError(err, file)
8688
callback(err)
8789
})
8890
}
@@ -102,7 +104,7 @@ Pass 3: Truncating between 25% and 75% of the file.`,
102104
.then(({ file }) => write.unlink(file))
103105
.then(() => callback())
104106
.catch((err) => {
105-
logError(err, file)
107+
eventError(err, file)
106108
callback(err)
107109
})
108110
}
@@ -120,7 +122,7 @@ Pass 2: Overwriting with random data.`,
120122
.then(({ file }) => write.unlink(file))
121123
.then(() => callback())
122124
.catch((err) => {
123-
logError(err, file)
125+
eventError(err, file)
124126
callback(err)
125127
})
126128
}
@@ -144,7 +146,7 @@ Pass 3: Overwriting with random data as well as verifying the writing of this da
144146
.then(({ file }) => write.unlink(file))
145147
.then(() => callback())
146148
.catch((err) => {
147-
logError(err, file)
149+
eventError(err, file)
148150
callback(err)
149151
})
150152
}
@@ -164,7 +166,7 @@ Pass 3: Overwriting with the complement of the 2nd pass, and verifying the writi
164166
.then(({ file }) => write.unlink(file))
165167
.then(() => callback())
166168
.catch((err) => {
167-
logError(err, file)
169+
eventError(err, file)
168170
callback(err)
169171
})
170172
}
@@ -190,7 +192,7 @@ Pass 7: Overwriting with a random data as well as review the writing of this cha
190192
.then(({ file }) => write.unlink(file))
191193
.then(() => callback())
192194
.catch((err) => {
193-
logError(err, file)
195+
eventError(err, file)
194196
callback(err)
195197
})
196198
}
@@ -210,7 +212,7 @@ Pass 3-7: Overwriting with random data.`,
210212
.then(({ file }) => write.unlink(file))
211213
.then(() => callback())
212214
.catch((err) => {
213-
logError(err, file)
215+
eventError(err, file)
214216
callback(err)
215217
})
216218
}
@@ -226,7 +228,7 @@ Pass 3-7: Overwriting with random data.`,
226228
.then(({ file }) => write.unlink(file))
227229
.then(() => callback())
228230
.catch((err) => {
229-
logError(err, file)
231+
eventError(err, file)
230232
callback(err)
231233
})
232234
}
@@ -256,7 +258,7 @@ Pass 32-35: Overwriting with random data.`,
256258
.then(({ file }) => write.unlink(file))
257259
.then(() => callback())
258260
.catch((err) => {
259-
logError(err, file)
261+
eventError(err, file)
260262
callback(err)
261263
})
262264
}

lib/secure-rm.js

+6
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,24 @@ const rimraf = require('rimraf')
22
const { methods, eventEmitter } = require('./methods')
33
const { write } = require('./write')
44

5+
// List of valid methods IDs
56
const validIDs = Array.from(Object.keys(methods))
67

8+
// Main function when secure-rm is called
79
function secureRm (path, options, callback) {
10+
// Parse if callback is provided
811
if (callback === undefined && typeof options === 'function') {
912
callback = options
1013
options = { method: 'secure' }
1114
}
15+
// Define method if none is provided
1216
if (options.method == null) options.method = 'secure'
1317

1418
if (callback) secureRmCallback(path, options, (err, path) => callback(err, path))
1519
else return secureRmPromise(path, options)
1620
}
1721

22+
// Callback version
1823
function secureRmCallback (path, options, callback) {
1924
if (options.customMethod) {
2025
rimraf(path, {
@@ -33,6 +38,7 @@ function secureRmCallback (path, options, callback) {
3338
}
3439
}
3540

41+
// Promise version
3642
function secureRmPromise (path, options) {
3743
return new Promise((resolve, reject) => {
3844
if (options.customMethod) {

lib/write.js

+13
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ const { kMaxLength } = require('buffer')
66

77
const eventEmitter = new events.EventEmitter()
88

9+
// Function to offset an array
910
const offset = (arr, offset) => [...arr.slice(offset), ...arr.slice(0, offset)]
1011

12+
// Object listing writing methods
1113
const write = {
14+
// Needed to provide file size
1215
init: file => {
1316
return new Promise((resolve, reject) => {
1417
fs.stat(file, (err, stats) => {
@@ -65,6 +68,7 @@ const write = {
6568
})
6669
})
6770
},
71+
// Write one byte on the whole file
6872
byte: (file, data, fileSize, passes) => {
6973
return new Promise((resolve, reject) => {
7074
eventEmitter.emit('info', file, `Writing 0x${data.toString(16)} `)
@@ -78,6 +82,7 @@ const write = {
7882
})
7983
})
8084
},
85+
// Write an array of bytes on the whole file
8186
bytes: (file, dataArray, fileSize, passes) => {
8287
return new Promise((resolve, reject) => {
8388
eventEmitter.emit('info', file, `Writing ${dataArray.map(x => '0x' + x.toString(16))} `)
@@ -92,6 +97,8 @@ const write = {
9297
})
9398
})
9499
},
100+
// Write an array of bytes on the whole file
101+
// And then cycle through the array
95102
cycleBytes: (file, dataArray, fileSize, passes = 1) => {
96103
return new Promise((resolve, reject) => {
97104
eventEmitter.emit('info', file, `Writing ${dataArray.map(x => '0x' + x.toString(16))} `)
@@ -106,6 +113,8 @@ const write = {
106113
})
107114
})
108115
},
116+
// Write start byte on the whole file
117+
// And then + increment until end byte
109118
incrementByte: (file, { start, end, increment }, fileSize) => {
110119
return new Promise((resolve, reject) => {
111120
eventEmitter.emit('info', file, `Writing 0x${start.toString(16)} `)
@@ -132,6 +141,7 @@ const write = {
132141
})
133142
})
134143
},
144+
// Write the binary complement
135145
complementary: (file, fileSize) => {
136146
return new Promise((resolve, reject) => {
137147
eventEmitter.emit('info', file, 'Reading file ')
@@ -151,6 +161,7 @@ const write = {
151161
})
152162
})
153163
},
164+
// Rename to random string
154165
rename: (file, fileSize) => {
155166
return new Promise((resolve, reject) => {
156167
const newName = crypto.randomBytes(9).toString('base64').replace(/\//g, '0').replace(/\+/g, 'a')
@@ -162,6 +173,7 @@ const write = {
162173
})
163174
})
164175
},
176+
// Truncate to between 25% and 75% of the file size
165177
truncate: (file, fileSize) => {
166178
return new Promise((resolve, reject) => {
167179
eventEmitter.emit('info', file, 'Truncating ')
@@ -172,6 +184,7 @@ const write = {
172184
})
173185
})
174186
},
187+
// End function: unlink the file pointer
175188
unlink: file => {
176189
return new Promise((resolve, reject) => {
177190
eventEmitter.emit('unlink', file)

0 commit comments

Comments
 (0)