From fd27e6f9dce1d49a2f731465e2ab979229503fa4 Mon Sep 17 00:00:00 2001 From: Sambo Chea Date: Mon, 14 Feb 2022 12:30:32 +0700 Subject: [PATCH] Task: Completed for cryptojs and tests functions and validate keys --- dummy/ase-256-16.key | 1 + dummy/ase-256-32.key | 1 + dummy/ase-256.json | 4 + dummy/ase-256.keys.json | 4 + dummy/private-key.pem | 1 + dummy/private-public.json | 4 + dummy/private-public.keys.json | 4 + dummy/public-key.pem | 1 + jest.config.js | 5 ++ package.json | 9 +- .../default.crypto.ts} | 18 ++-- .../{e2e-crypto.ts => core/e2e.crypto.ts} | 14 ++-- src/crypto/crypto.ts | 21 +++++ src/crypto/index.ts | 21 ++++- src/crypto/provider.crypto.ts | 4 + src/crypto/provider/default.provider.ts | 33 ++++++++ src/crypto/provider/e2e.provider.ts | 82 +++++++++++++++++++ src/util/file.util.ts | 6 +- src/util/index.ts | 29 ++++++- src/util/test.util.ts | 22 +++++ test/crypto.test.ts | 3 + test/validate-ase.test.ts | 31 +++++++ test/validate-priv-pub.test.ts | 30 +++++++ 23 files changed, 324 insertions(+), 24 deletions(-) create mode 100644 dummy/ase-256-16.key create mode 100644 dummy/ase-256-32.key create mode 100644 dummy/ase-256.json create mode 100644 dummy/ase-256.keys.json create mode 100644 dummy/private-key.pem create mode 100644 dummy/private-public.json create mode 100644 dummy/private-public.keys.json create mode 100644 dummy/public-key.pem create mode 100644 jest.config.js rename src/crypto/{default-crypto.ts => core/default.crypto.ts} (72%) rename src/crypto/{e2e-crypto.ts => core/e2e.crypto.ts} (53%) create mode 100644 src/crypto/crypto.ts create mode 100644 src/crypto/provider.crypto.ts create mode 100644 src/crypto/provider/default.provider.ts create mode 100644 src/crypto/provider/e2e.provider.ts create mode 100644 src/util/test.util.ts create mode 100644 test/crypto.test.ts create mode 100644 test/validate-ase.test.ts create mode 100644 test/validate-priv-pub.test.ts diff --git a/dummy/ase-256-16.key b/dummy/ase-256-16.key new file mode 100644 index 0000000..afea216 --- /dev/null +++ b/dummy/ase-256-16.key @@ -0,0 +1 @@ +6ef348dd9b0b4f29e47f4f1c9d7b6255 \ No newline at end of file diff --git a/dummy/ase-256-32.key b/dummy/ase-256-32.key new file mode 100644 index 0000000..e9456e2 --- /dev/null +++ b/dummy/ase-256-32.key @@ -0,0 +1 @@ +56773703de5fdbe4292749c2505b6059a6698aad7881065df0818442f7d559b2 \ No newline at end of file diff --git a/dummy/ase-256.json b/dummy/ase-256.json new file mode 100644 index 0000000..acc2514 --- /dev/null +++ b/dummy/ase-256.json @@ -0,0 +1,4 @@ +{ + "key": "56773703de5fdbe4292749c2505b6059a6698aad7881065df0818442f7d559b2", + "iv": "6ef348dd9b0b4f29e47f4f1c9d7b6255" +} diff --git a/dummy/ase-256.keys.json b/dummy/ase-256.keys.json new file mode 100644 index 0000000..8c3d731 --- /dev/null +++ b/dummy/ase-256.keys.json @@ -0,0 +1,4 @@ +{ + "keyPath": "./dummy/ase-256-32.key", + "ivPath": "./dummy/ase-256-16.key" +} diff --git a/dummy/private-key.pem b/dummy/private-key.pem new file mode 100644 index 0000000..28cfe96 --- /dev/null +++ b/dummy/private-key.pem @@ -0,0 +1 @@ +-----BEGIN RSA PRIVATE KEY----- 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 -----END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/dummy/private-public.json b/dummy/private-public.json new file mode 100644 index 0000000..05d0c9b --- /dev/null +++ b/dummy/private-public.json @@ -0,0 +1,4 @@ +{ + "privateKey": "-----BEGIN RSA PRIVATE KEY----- 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 -----END RSA PRIVATE KEY-----", + "publicKey": "-----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0PfjoO54+QZui0EfssxG vHOm8bhDzQIIDcH/jUvN25E28MYFVOy1CgDk2n25eakhaaK8ogmP9PfczGpLalCG fVACCXNQFc60k6zjQY8lNY6DY2NJ4qGR5OZsA2lhXgYtptqHCvGnqqIBpfYkddKz ZOjQGZvUQ3XVZvEpkDuJGvPFW/+B4NjsgSK0bJzygnJnbJYUHezBVRQynJRIxJmC ZfuhqJM2w0FLB1/8TZVn9w3OC3DXavU7DfEGOlJb9evRrvdVGag14Pcy6SXoZ1jF scRJuXyWy1mLooTx6osj7V6VYhnKZJrlRTAUxnGZLuBdqYztU7SNhZfmuCSIS+nd uqrdM9P3NPqgOqmIMTps0fcQg0DU5CFdWIy/FecErg1YaAhbEOqQO4QQlTmMDFFJ 63Y9rE3s9W5k30ZP8Ydxa8UT3su36ePzUGzWXUu2M8ffc8nnfiAvh1XgJiBqDJkm VEG3GzmDL0BfDLqMnhBJ2UaQPXK9w52masDgvHvyMEZoBaFBHtVICl4Jek6O9KSz 1uWcR/+C72fBEU4iA/h4rdH4PVMTP99YhN+Zd4w9UM2tITafCM3RdNbKZ3f+oXfF CjqNKiJI/VSLkErOKQnw/AiGT8dpmmFGl+DazUsYNEP3ScFUAI+ZqsUyh5q9SoCn YmcpuMbXLRLVYQJQASkYwBkCAwEAAQ== -----END PUBLIC KEY-----" +} diff --git a/dummy/private-public.keys.json b/dummy/private-public.keys.json new file mode 100644 index 0000000..7ea80ee --- /dev/null +++ b/dummy/private-public.keys.json @@ -0,0 +1,4 @@ +{ + "privateKeyPath": "./dummy/private-key.pem", + "publicKeyPath": "./dummy/public-key.pem" +} diff --git a/dummy/public-key.pem b/dummy/public-key.pem new file mode 100644 index 0000000..2baaa77 --- /dev/null +++ b/dummy/public-key.pem @@ -0,0 +1 @@ +-----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0PfjoO54+QZui0EfssxG vHOm8bhDzQIIDcH/jUvN25E28MYFVOy1CgDk2n25eakhaaK8ogmP9PfczGpLalCG fVACCXNQFc60k6zjQY8lNY6DY2NJ4qGR5OZsA2lhXgYtptqHCvGnqqIBpfYkddKz ZOjQGZvUQ3XVZvEpkDuJGvPFW/+B4NjsgSK0bJzygnJnbJYUHezBVRQynJRIxJmC ZfuhqJM2w0FLB1/8TZVn9w3OC3DXavU7DfEGOlJb9evRrvdVGag14Pcy6SXoZ1jF scRJuXyWy1mLooTx6osj7V6VYhnKZJrlRTAUxnGZLuBdqYztU7SNhZfmuCSIS+nd uqrdM9P3NPqgOqmIMTps0fcQg0DU5CFdWIy/FecErg1YaAhbEOqQO4QQlTmMDFFJ 63Y9rE3s9W5k30ZP8Ydxa8UT3su36ePzUGzWXUu2M8ffc8nnfiAvh1XgJiBqDJkm VEG3GzmDL0BfDLqMnhBJ2UaQPXK9w52masDgvHvyMEZoBaFBHtVICl4Jek6O9KSz 1uWcR/+C72fBEU4iA/h4rdH4PVMTP99YhN+Zd4w9UM2tITafCM3RdNbKZ3f+oXfF CjqNKiJI/VSLkErOKQnw/AiGT8dpmmFGl+DazUsYNEP3ScFUAI+ZqsUyh5q9SoCn YmcpuMbXLRLVYQJQASkYwBkCAwEAAQ== -----END PUBLIC KEY----- \ No newline at end of file diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..30c3292 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,5 @@ +module.exports = { + preset: "ts-jest", + testEnvironment: "node", + modulePathIgnorePatterns: ["/build/"], +} diff --git a/package.json b/package.json index a2d2776..c6e8339 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "start": "ts-node-dev --respawn --transpile-only src/index.ts", "build": "rm -rf dist && tsc", "serve": "npm run build && node dist/index.js", - "test": "echo \"Error: no test specified\" && exit 1", + "test": "jest", "prepare": "husky install" }, "repository": { @@ -23,6 +23,8 @@ "author": "Sambo Chea ", "license": "ISC", "devDependencies": { + "@types/jest": "^27.4.0", + "@types/node": "^16.9.1", "@typescript-eslint/eslint-plugin": "^4.30.0", "@typescript-eslint/parser": "^4.30.0", "eslint": "^7.32.0", @@ -30,11 +32,12 @@ "eslint-plugin-jsdoc": "^36.0.8", "eslint-plugin-prefer-arrow": "^1.2.3", "husky": "^7.0.2", + "jest": "^27.5.1", "lint-staged": "^11.1.2", "prettier": "2.3.2", + "ts-jest": "^27.1.3", "ts-node-dev": "^1.1.8", - "typescript": "^4.4.2", - "@types/node": "^16.9.1" + "typescript": "^4.4.2" }, "lint-staged": { "**/*": "prettier --write --ignore-unknown" diff --git a/src/crypto/default-crypto.ts b/src/crypto/core/default.crypto.ts similarity index 72% rename from src/crypto/default-crypto.ts rename to src/crypto/core/default.crypto.ts index 25907fd..9dc3d30 100644 --- a/src/crypto/default-crypto.ts +++ b/src/crypto/core/default.crypto.ts @@ -3,11 +3,11 @@ import { DEFAULT_AES_ALGORITHM, DEFAULT_BUFFER_TYPE, DEFAULT_ENCODING_TYPE, -} from "../config" -import { stringToBuffer } from "../util" +} from "../../config" +import { bufferToString, stringToBuffer } from "../../util" const encrypt = ( - data: string, + data: string | Buffer, key: string | Buffer, iv?: string | Buffer | null ): string => { @@ -16,8 +16,9 @@ const encrypt = ( stringToBuffer(key), stringToBuffer(iv || key) ) + const _data = bufferToString(data) let encrypted = cipher.update( - data, + _data, DEFAULT_ENCODING_TYPE, DEFAULT_BUFFER_TYPE ) @@ -25,14 +26,19 @@ const encrypt = ( return encrypted } -const decrypt = (data: string, key: Buffer, iv?: Buffer | null): string => { +const decrypt = ( + data: string | Buffer, + key: string | Buffer, + iv?: string | Buffer | null +): string => { const decipher = crypto.createDecipheriv( DEFAULT_AES_ALGORITHM, stringToBuffer(key), stringToBuffer(iv || key) ) + const _data = bufferToString(data) let decrypted = decipher.update( - data, + _data, DEFAULT_BUFFER_TYPE, DEFAULT_ENCODING_TYPE ) diff --git a/src/crypto/e2e-crypto.ts b/src/crypto/core/e2e.crypto.ts similarity index 53% rename from src/crypto/e2e-crypto.ts rename to src/crypto/core/e2e.crypto.ts index 1d22551..08b78f5 100644 --- a/src/crypto/e2e-crypto.ts +++ b/src/crypto/core/e2e.crypto.ts @@ -1,25 +1,23 @@ import * as crypto from "crypto" -import { DEFAULT_BUFFER_TYPE, DEFAULT_ENCODING_TYPE } from "../config" -import { readFileString, stringToBuffer } from "../util" +import { DEFAULT_BUFFER_TYPE, DEFAULT_ENCODING_TYPE } from "../../config" +import { stringToBuffer } from "../../util" -const encrypt = (data: string | Buffer, privOrPubKeyPath: string): string => { - const key = readFileString(privOrPubKeyPath) +const encrypt = (data: string | Buffer, privateOrPublicKey: string): string => { const buffer = stringToBuffer(data) - const encrypted = crypto.publicEncrypt(key, buffer) + const encrypted = crypto.publicEncrypt(privateOrPublicKey, buffer) return encrypted.toString(DEFAULT_BUFFER_TYPE) } const decrypt = ( data: string | Buffer, - privateKeyPath: string, + privateKey: string, passphrase?: string | null ): string => { - const key = readFileString(privateKeyPath) const buffer = stringToBuffer(data) const decrypted = crypto.privateDecrypt( { - key: key, + key: privateKey, passphrase: passphrase || "", }, buffer diff --git a/src/crypto/crypto.ts b/src/crypto/crypto.ts new file mode 100644 index 0000000..7f03d12 --- /dev/null +++ b/src/crypto/crypto.ts @@ -0,0 +1,21 @@ +import { ICryptoProvider } from "./provider.crypto" + +export class CryptoProvider { + constructor(private readonly provider: ICryptoProvider) {} + + public encrypt(data: string | Buffer): string { + return this.provider.encrypt(data) + } + + public decrypt(data: string): string { + return this.provider.decrypt(data) + } + + private static _instance: CryptoProvider | null | undefined + public static newInstance(provider: ICryptoProvider): CryptoProvider { + if (!CryptoProvider._instance) { + CryptoProvider._instance = new CryptoProvider(provider) + } + return CryptoProvider._instance + } +} diff --git a/src/crypto/index.ts b/src/crypto/index.ts index 5e5b39e..4f843fb 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -1,4 +1,19 @@ -import { decrypt, encrypt } from "./default-crypto" -import { encrypt as e2eEncrypt, decrypt as e2eDecrypt } from "./e2e-crypto" +import { decrypt, encrypt } from "./core/default.crypto" +import { encrypt as e2eEncrypt, decrypt as e2eDecrypt } from "./core/e2e.crypto" +import { CryptoProvider } from "./crypto" +import { ICryptoProvider } from "./provider.crypto" +import { DefaultCryptoProvider } from "./provider/default.provider" +import { E2ECryptoProvider } from "./provider/e2e.provider" -export { encrypt, decrypt, e2eEncrypt, e2eDecrypt } +export { + encrypt, + decrypt, + e2eEncrypt, + e2eDecrypt, + // Some implementations of ICryptoProvider + ICryptoProvider, + DefaultCryptoProvider, + E2ECryptoProvider, + // Core crypto functions + CryptoProvider, +} diff --git a/src/crypto/provider.crypto.ts b/src/crypto/provider.crypto.ts new file mode 100644 index 0000000..8df2fbd --- /dev/null +++ b/src/crypto/provider.crypto.ts @@ -0,0 +1,4 @@ +export interface ICryptoProvider { + encrypt(data: string | Buffer): string + decrypt(data: string): string +} diff --git a/src/crypto/provider/default.provider.ts b/src/crypto/provider/default.provider.ts new file mode 100644 index 0000000..101c04e --- /dev/null +++ b/src/crypto/provider/default.provider.ts @@ -0,0 +1,33 @@ +import { assertNotNullOrUndefined } from "../../util" +import { ICryptoProvider } from "../provider.crypto" +import { decrypt as dec, encrypt as enc } from "./../core/default.crypto" + +export class DefaultCryptoProvider implements ICryptoProvider { + private _key: string | Buffer | null | undefined + private _iv: string | Buffer | null | undefined + + constructor( + key?: string | Buffer | null, + iv?: string | Buffer | null, + keyJsonFilePath?: string | null + ) { + if (keyJsonFilePath) { + const json: any = require(keyJsonFilePath) + this._key = json.key + this._iv = json.iv + } else { + this._key = key + this._iv = iv || key + } + + assertNotNullOrUndefined(this._key, "key is required") + } + + encrypt(data: string | Buffer): string { + return enc(data, this._key!, this._iv) + } + + decrypt(data: string): string { + return dec(data, this._key!, this._iv) + } +} diff --git a/src/crypto/provider/e2e.provider.ts b/src/crypto/provider/e2e.provider.ts new file mode 100644 index 0000000..de91385 --- /dev/null +++ b/src/crypto/provider/e2e.provider.ts @@ -0,0 +1,82 @@ +import { e2eDecrypt, e2eEncrypt } from ".." +import { + assertNotNullOrUndefined, + isNullOrUndefinedOrEmpty, + readFileToString, +} from "../../util" +import { ICryptoProvider } from "../provider.crypto" + +export class E2ECryptoProvider implements ICryptoProvider { + private privateKey: string | Buffer | null | undefined + private publicKey: string | Buffer | null | undefined + + constructor( + privateKey?: string | Buffer | null | undefined, + publicKey?: string | Buffer | null | undefined, + privateKeyPath?: string | null | undefined, + publicKeyPath?: string | null | undefined, + jsonPath?: string | null | undefined + ) { + let isPrivateKeyInitialized = false + let isPublicKeyInitialized = false + if (privateKeyPath) { + this.privateKey = readFileToString(privateKeyPath) + isPrivateKeyInitialized = !isNullOrUndefinedOrEmpty(this.privateKey) + } + + if (publicKeyPath) { + this.publicKey = readFileToString(publicKeyPath) + isPublicKeyInitialized = !isNullOrUndefinedOrEmpty(this.publicKey) + } + + if (!isPrivateKeyInitialized && !isPublicKeyInitialized && jsonPath) { + const json = require(jsonPath) + if (json.privateKey) { + this.privateKey = json.privateKey + isPrivateKeyInitialized = !isNullOrUndefinedOrEmpty( + this.privateKey + ) + } + + if (json.publicKey) { + this.publicKey = json.publicKey + isPublicKeyInitialized = !isNullOrUndefinedOrEmpty( + this.publicKey + ) + } + + if (!isPrivateKeyInitialized && json.privateKeyPath) { + this.privateKey = readFileToString(json.privateKeyPath) + isPrivateKeyInitialized = !isNullOrUndefinedOrEmpty( + this.privateKey + ) + } + + if (!isPublicKeyInitialized && json.publicKeyPath) { + this.publicKey = readFileToString(json.publicKeyPath) + isPublicKeyInitialized = !isNullOrUndefinedOrEmpty( + this.publicKey + ) + } + } + + if (!isPrivateKeyInitialized) { + this.privateKey = privateKey + } + + if (!isPublicKeyInitialized) { + this.publicKey = publicKey + } + + assertNotNullOrUndefined(this.privateKey, "Private key is required") + } + + encrypt(data: string | Buffer): string { + const key = this.publicKey || this.privateKey + return e2eEncrypt(data, key!.toString()) + } + + decrypt(data: string): string { + return e2eDecrypt(data, this.privateKey!.toString()) + } +} diff --git a/src/util/file.util.ts b/src/util/file.util.ts index 496cb36..81181c5 100644 --- a/src/util/file.util.ts +++ b/src/util/file.util.ts @@ -2,9 +2,13 @@ import * as fs from "fs" import * as path from "path" import { DEFAULT_ENCODING_TYPE } from "../config" -export const readFileStringDefaultEncoding = ( +export const readFileToStringDefaultEncoding = ( relativeFilePath: string ): string => { const absolutePath = path.resolve(relativeFilePath) return fs.readFileSync(absolutePath, DEFAULT_ENCODING_TYPE) } + +export const readFileToJson = (relativeFilePath: string): any => { + return JSON.parse(readFileToStringDefaultEncoding(relativeFilePath)) +} diff --git a/src/util/index.ts b/src/util/index.ts index 1afd556..1357098 100644 --- a/src/util/index.ts +++ b/src/util/index.ts @@ -1,5 +1,11 @@ -import { DEFAULT_BUFFER_TYPE } from "../config" -import { readFileStringDefaultEncoding } from "./file.util" +import { DEFAULT_BUFFER_TYPE, DEFAULT_ENCODING_TYPE } from "../config" +import { readFileToStringDefaultEncoding, readFileToJson } from "./file.util" +import { + assertNotNullOrUndefined, + assertNotNullOrUndefinedOrEmpty, + isNullOrUndefined, + isNullOrUndefinedOrEmpty, +} from "./test.util" const stringToBuffer = (data: string | Buffer): Buffer => { if (data instanceof Buffer) { @@ -9,4 +15,21 @@ const stringToBuffer = (data: string | Buffer): Buffer => { } } -export { readFileStringDefaultEncoding as readFileString, stringToBuffer } +const bufferToString = (data: string | Buffer): string => { + if (data instanceof Buffer) { + return data.toString(DEFAULT_ENCODING_TYPE) + } else { + return data + } +} + +export { + readFileToStringDefaultEncoding as readFileToString, + readFileToJson, + stringToBuffer, + bufferToString, + assertNotNullOrUndefined, + assertNotNullOrUndefinedOrEmpty, + isNullOrUndefined, + isNullOrUndefinedOrEmpty, +} diff --git a/src/util/test.util.ts b/src/util/test.util.ts new file mode 100644 index 0000000..e9f9d37 --- /dev/null +++ b/src/util/test.util.ts @@ -0,0 +1,22 @@ +export const assertNotNullOrUndefined = (value: unknown, msg?: string) => { + if (isNullOrUndefined(value)) { + throw new Error(msg || "value is null or undefined") + } +} + +export const assertNotNullOrUndefinedOrEmpty = ( + value: unknown, + msg?: string +) => { + if (isNullOrUndefinedOrEmpty(value)) { + throw new Error(msg || "value is null or undefined or empty") + } +} + +export const isNullOrUndefined = (value: unknown): boolean => { + return value === null || value === undefined +} + +export const isNullOrUndefinedOrEmpty = (value: unknown): boolean => { + return isNullOrUndefined(value) || value === "" +} diff --git a/test/crypto.test.ts b/test/crypto.test.ts new file mode 100644 index 0000000..b514102 --- /dev/null +++ b/test/crypto.test.ts @@ -0,0 +1,3 @@ +test("test", () => { + expect(1).toBe(1) +}) diff --git a/test/validate-ase.test.ts b/test/validate-ase.test.ts new file mode 100644 index 0000000..de7685f --- /dev/null +++ b/test/validate-ase.test.ts @@ -0,0 +1,31 @@ +import { readFileToString, readFileToJson } from "./../src/util" + +test("test: readFileToString", () => { + const value1 = readFileToString("./dummy/ase-256-32.key") + const value2 = readFileToString("./dummy/ase-256-16.key") + + expect(value1).toBe( + "56773703de5fdbe4292749c2505b6059a6698aad7881065df0818442f7d559b2" + ) + expect(value2).toBe("6ef348dd9b0b4f29e47f4f1c9d7b6255") +}) + +test("test: readFileToString with jsonFile key-paths", () => { + const json = readFileToJson("./dummy/ase-256.keys.json") + const value1 = readFileToString(json.keyPath) + const value2 = readFileToString(json.ivPath) + expect(value1).toBe( + "56773703de5fdbe4292749c2505b6059a6698aad7881065df0818442f7d559b2" + ) + expect(value2).toBe("6ef348dd9b0b4f29e47f4f1c9d7b6255") +}) + +test("test: readFileToString with jsonFile values", () => { + const json = readFileToJson("./dummy/ase-256.json") + const value1 = json.key + const value2 = json.iv + expect(value1).toBe( + "56773703de5fdbe4292749c2505b6059a6698aad7881065df0818442f7d559b2" + ) + expect(value2).toBe("6ef348dd9b0b4f29e47f4f1c9d7b6255") +}) diff --git a/test/validate-priv-pub.test.ts b/test/validate-priv-pub.test.ts new file mode 100644 index 0000000..f341e42 --- /dev/null +++ b/test/validate-priv-pub.test.ts @@ -0,0 +1,30 @@ +import { readFileToString, readFileToJson } from "./../src/util" + +const PRIVATE_KEY_VALUE = + "-----BEGIN RSA PRIVATE KEY----- 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 -----END RSA PRIVATE KEY-----" +const PUBLIC_KEY_VALUE = + "-----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0PfjoO54+QZui0EfssxG vHOm8bhDzQIIDcH/jUvN25E28MYFVOy1CgDk2n25eakhaaK8ogmP9PfczGpLalCG fVACCXNQFc60k6zjQY8lNY6DY2NJ4qGR5OZsA2lhXgYtptqHCvGnqqIBpfYkddKz ZOjQGZvUQ3XVZvEpkDuJGvPFW/+B4NjsgSK0bJzygnJnbJYUHezBVRQynJRIxJmC ZfuhqJM2w0FLB1/8TZVn9w3OC3DXavU7DfEGOlJb9evRrvdVGag14Pcy6SXoZ1jF scRJuXyWy1mLooTx6osj7V6VYhnKZJrlRTAUxnGZLuBdqYztU7SNhZfmuCSIS+nd uqrdM9P3NPqgOqmIMTps0fcQg0DU5CFdWIy/FecErg1YaAhbEOqQO4QQlTmMDFFJ 63Y9rE3s9W5k30ZP8Ydxa8UT3su36ePzUGzWXUu2M8ffc8nnfiAvh1XgJiBqDJkm VEG3GzmDL0BfDLqMnhBJ2UaQPXK9w52masDgvHvyMEZoBaFBHtVICl4Jek6O9KSz 1uWcR/+C72fBEU4iA/h4rdH4PVMTP99YhN+Zd4w9UM2tITafCM3RdNbKZ3f+oXfF CjqNKiJI/VSLkErOKQnw/AiGT8dpmmFGl+DazUsYNEP3ScFUAI+ZqsUyh5q9SoCn YmcpuMbXLRLVYQJQASkYwBkCAwEAAQ== -----END PUBLIC KEY-----" + +test("test: readFileToString with private and public key files", () => { + const value1 = readFileToString("./dummy/private-key.pem") + const value2 = readFileToString("./dummy/public-key.pem") + + expect(value1).toBe(PRIVATE_KEY_VALUE) + expect(value2).toBe(PUBLIC_KEY_VALUE) +}) + +test("test: readFileToString with private and public jsonFile key-paths", () => { + const json = readFileToJson("./dummy/private-public.keys.json") + const value1 = readFileToString(json.privateKeyPath) + const value2 = readFileToString(json.publicKeyPath) + expect(value1).toBe(PRIVATE_KEY_VALUE) + expect(value2).toBe(PUBLIC_KEY_VALUE) +}) + +test("test: readFileToString with private and public jsonFile values", () => { + const json = readFileToJson("./dummy/private-public.json") + const value1 = json.privateKey + const value2 = json.publicKey + expect(value1).toBe(PRIVATE_KEY_VALUE) + expect(value2).toBe(PUBLIC_KEY_VALUE) +})