stegdoc 4.0.0 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +200 -214
- package/package.json +59 -59
- package/src/commands/decode.js +485 -343
- package/src/commands/encode.js +567 -449
- package/src/commands/info.js +118 -114
- package/src/commands/verify.js +207 -204
- package/src/index.js +89 -87
- package/src/lib/compression.js +177 -115
- package/src/lib/crypto.js +172 -172
- package/src/lib/decoy-generator.js +306 -306
- package/src/lib/docx-handler.js +587 -161
- package/src/lib/docx-templates.js +355 -0
- package/src/lib/file-handler.js +113 -113
- package/src/lib/file-utils.js +160 -150
- package/src/lib/interactive.js +190 -190
- package/src/lib/log-generator.js +764 -0
- package/src/lib/metadata.js +151 -122
- package/src/lib/streams.js +197 -197
- package/src/lib/utils.js +227 -227
- package/src/lib/xlsx-handler.js +597 -416
- package/src/lib/xml-utils.js +115 -115
package/src/commands/info.js
CHANGED
|
@@ -1,114 +1,118 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
const chalk = require('chalk');
|
|
3
|
-
const ora = require('ora');
|
|
4
|
-
const { readDocxBase64 } = require('../lib/docx-handler');
|
|
5
|
-
const { readXlsxBase64 } = require('../lib/xlsx-handler');
|
|
6
|
-
const { validateMetadata, isMultiPart } = require('../lib/metadata');
|
|
7
|
-
const { detectFormat, formatBytes } = require('../lib/utils');
|
|
8
|
-
const { extractContent, findMultiPartFiles } = require('../lib/file-utils');
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Show information about an encoded file without decoding
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
console.log();
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
console.log(chalk.
|
|
52
|
-
console.log(chalk.cyan(`
|
|
53
|
-
console.log(chalk.cyan(`
|
|
54
|
-
console.log();
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
console.log(chalk.
|
|
58
|
-
console.log(chalk.cyan(`
|
|
59
|
-
console.log(chalk.cyan(`
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
console.log(chalk.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
console.log(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
console.log(chalk.
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const chalk = require('chalk');
|
|
3
|
+
const ora = require('ora');
|
|
4
|
+
const { readDocxBase64 } = require('../lib/docx-handler');
|
|
5
|
+
const { readXlsxBase64 } = require('../lib/xlsx-handler');
|
|
6
|
+
const { validateMetadata, isMultiPart, isLogEmbedFormat } = require('../lib/metadata');
|
|
7
|
+
const { detectFormat, formatBytes } = require('../lib/utils');
|
|
8
|
+
const { extractContent, findMultiPartFiles } = require('../lib/file-utils');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Show information about an encoded file without decoding
|
|
12
|
+
*/
|
|
13
|
+
async function infoCommand(inputFile, options) {
|
|
14
|
+
const spinner = ora('Reading file metadata...').start();
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const format = detectFormat(inputFile);
|
|
18
|
+
if (!format) {
|
|
19
|
+
throw new Error('Unknown file format. Supported formats: .xlsx, .docx');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let readResult;
|
|
23
|
+
if (format === 'xlsx') {
|
|
24
|
+
readResult = await readXlsxBase64(inputFile);
|
|
25
|
+
} else {
|
|
26
|
+
readResult = await readDocxBase64(inputFile);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const extracted = extractContent(readResult, format);
|
|
30
|
+
const metadata = extracted.metadata;
|
|
31
|
+
const encryptionMeta = extracted.encryptionMeta;
|
|
32
|
+
|
|
33
|
+
validateMetadata(metadata);
|
|
34
|
+
|
|
35
|
+
const isEncrypted = metadata.encrypted || (encryptionMeta && encryptionMeta.length > 0);
|
|
36
|
+
const isCompressed = metadata.compressed || false;
|
|
37
|
+
const isV5 = isLogEmbedFormat(metadata);
|
|
38
|
+
|
|
39
|
+
spinner.succeed('File metadata read successfully');
|
|
40
|
+
console.log();
|
|
41
|
+
|
|
42
|
+
console.log(chalk.bold.white('File Information:'));
|
|
43
|
+
console.log(chalk.cyan(` Format: ${format.toUpperCase()}`));
|
|
44
|
+
console.log(chalk.cyan(` Tool version: ${metadata.version || '1.x'}`));
|
|
45
|
+
if (isV5) {
|
|
46
|
+
console.log(chalk.cyan(` Stego method: Log-embed (v5)`));
|
|
47
|
+
console.log(chalk.cyan(` Compression: ${metadata.compressionAlgo || 'brotli'}`));
|
|
48
|
+
}
|
|
49
|
+
console.log();
|
|
50
|
+
|
|
51
|
+
console.log(chalk.bold.white('Original File:'));
|
|
52
|
+
console.log(chalk.cyan(` Filename: ${metadata.originalFilename}`));
|
|
53
|
+
console.log(chalk.cyan(` Extension: ${metadata.originalExtension}`));
|
|
54
|
+
console.log(chalk.cyan(` Size: ${formatBytes(metadata.originalSize)}`));
|
|
55
|
+
console.log();
|
|
56
|
+
|
|
57
|
+
console.log(chalk.bold.white('Encoding Options:'));
|
|
58
|
+
console.log(chalk.cyan(` Encrypted: ${isEncrypted ? chalk.yellow('Yes') : 'No'}`));
|
|
59
|
+
console.log(chalk.cyan(` Compressed: ${isCompressed ? chalk.green('Yes') : 'No'}`));
|
|
60
|
+
console.log(chalk.cyan(` Encoded on: ${metadata.encodingDate || 'Unknown'}`));
|
|
61
|
+
|
|
62
|
+
if (metadata.contentHash) {
|
|
63
|
+
console.log(chalk.cyan(` Content hash: ${metadata.contentHash.slice(0, 16)}...`));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (isV5 && metadata.dataLineCount) {
|
|
67
|
+
console.log(chalk.cyan(` Data lines: ${metadata.dataLineCount}`));
|
|
68
|
+
}
|
|
69
|
+
console.log();
|
|
70
|
+
|
|
71
|
+
const hasMultipleParts = isMultiPart(metadata) || metadata.partNumber !== null;
|
|
72
|
+
if (hasMultipleParts) {
|
|
73
|
+
console.log(chalk.bold.white('Multi-part File:'));
|
|
74
|
+
const inputDir = path.dirname(inputFile);
|
|
75
|
+
const allParts = findMultiPartFiles(inputDir, metadata.hash, format);
|
|
76
|
+
const totalParts = metadata.totalParts || allParts.length;
|
|
77
|
+
|
|
78
|
+
console.log(chalk.cyan(` This is part: ${metadata.partNumber} of ${totalParts}`));
|
|
79
|
+
console.log(chalk.cyan(` Hash: ${metadata.hash}`));
|
|
80
|
+
|
|
81
|
+
console.log();
|
|
82
|
+
console.log(chalk.bold.white('Parts found in directory:'));
|
|
83
|
+
|
|
84
|
+
for (let i = 1; i <= totalParts; i++) {
|
|
85
|
+
const part = allParts.find(p => p.partNumber === i);
|
|
86
|
+
if (part) {
|
|
87
|
+
console.log(chalk.green(` ✓ Part ${i}: ${part.filename}`));
|
|
88
|
+
} else {
|
|
89
|
+
console.log(chalk.red(` ✗ Part ${i}: MISSING`));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (allParts.length >= totalParts) {
|
|
94
|
+
console.log();
|
|
95
|
+
console.log(chalk.green.bold('All parts found - ready to decode'));
|
|
96
|
+
} else {
|
|
97
|
+
console.log();
|
|
98
|
+
console.log(chalk.yellow.bold(`Missing ${totalParts - allParts.length} part(s)`));
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
console.log(chalk.bold.white('Single File:'));
|
|
102
|
+
console.log(chalk.cyan(` Hash: ${metadata.hash}`));
|
|
103
|
+
console.log();
|
|
104
|
+
console.log(chalk.green.bold('Ready to decode'));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (isEncrypted) {
|
|
108
|
+
console.log(chalk.yellow('\nNote: Password required for decoding'));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
} catch (error) {
|
|
112
|
+
spinner.fail('Failed to read file info');
|
|
113
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
module.exports = infoCommand;
|