Skip to content

Commit d6d9bb5

Browse files
committed
support postprocessing steps and fix examples
1 parent 7810b4e commit d6d9bb5

8 files changed

Lines changed: 318 additions & 197 deletions

File tree

examples/file_based_usage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const OUTPUT_PATH = join(__dirname, 'output', 'output_10.csv');
1313
const VALIDATION_ERRORS_PATH = join(__dirname, 'output', 'validation_errors.csv');
1414

1515
// load configuration from file
16-
const configLoadResult = loadConfig(CONFIG_PATH, ALGORITHM_ID);
16+
const configLoadResult = loadConfig({ configPath: CONFIG_PATH, algorithmId: ALGORITHM_ID });
1717
if (!configLoadResult.success) throw new Error(`ERROR: Unable to load configuration file >> ${configLoadResult.error}`);
1818

1919
// validate the input file against all configured validation rules.

package-lock.json

Lines changed: 47 additions & 37 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"date-fns": "^4.1.0",
4141
"debug": "^4.3.7",
4242
"hi-base32": "^0.5.1",
43+
"openpgp": "^6.2.2",
4344
"safe-stable-stringify": "^2.4.3",
4445
"toml": "^3.0.0",
4546
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"

src/processing/index.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@
1414
// You should have received a copy of the GNU Affero General Public License
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

17-
export {
18-
generateHashesForDocument,
19-
preprocessFile,
20-
processFile,
21-
validateDocument,
22-
} from './processing';
17+
export { preprocessFile, validateDocument } from './preprocess';
18+
export { generateHashesForDocument, processFile } from './process';
19+
export { postprocessFile, encryptFile } from './postprocess';
2320
export { keepOutputColumns } from './mapping';

src/processing/postprocess.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// Common Identifier Application
2+
// Copyright (C) 2024 World Food Programme
3+
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
import * as openpgp from 'openpgp';
18+
import { createReadStream, createWriteStream, readFileSync } from 'fs';
19+
import { pipeline } from 'stream/promises';
20+
import { Readable } from 'stream';
21+
22+
import type { Config } from '../config/Config';
23+
24+
import Debug from 'debug';
25+
const log = Debug('CID:postprocessFile');
26+
27+
28+
export interface PostprocessFileResult {
29+
encryptedFilePath?: string
30+
}
31+
32+
interface PostprocessFileInput {
33+
config: Config.FileConfiguration,
34+
filePath: string
35+
}
36+
37+
export async function postprocessFile({ config, filePath }: PostprocessFileInput): Promise<PostprocessFileResult> {
38+
log('------------ postprocessFile -----------------');
39+
let encryptedFilePath: string | undefined;
40+
41+
if (!config.post_processing) return {}
42+
43+
if (config.post_processing.encryption) {
44+
encryptedFilePath = await encryptFile({
45+
filePath: filePath,
46+
keyPath: config.post_processing.encryption.key_path
47+
});
48+
}
49+
50+
return {
51+
encryptedFilePath
52+
}
53+
}
54+
55+
56+
type EncryptFileInput = {
57+
filePath: string;
58+
keyPath: string;
59+
}
60+
export async function encryptFile({ filePath, keyPath }: EncryptFileInput) {
61+
const publicKeyArmoured = readFileSync(keyPath, "utf-8");
62+
const publicKey = await openpgp.readKey({ armoredKey: publicKeyArmoured });
63+
64+
const webStream = Readable.toWeb(createReadStream(filePath));
65+
66+
const encryptionStream = await openpgp.encrypt({
67+
message: await openpgp.createMessage({ binary: webStream }),
68+
encryptionKeys: publicKey,
69+
format: "binary"
70+
});
71+
72+
const outputPath = `${filePath}.gpg`;
73+
74+
const nodeWritable = createWriteStream(outputPath);
75+
const nodeReadable = Readable.fromWeb(encryptionStream);
76+
77+
await pipeline(nodeReadable, nodeWritable);
78+
79+
return outputPath;
80+
}

0 commit comments

Comments
 (0)