@sap_oss/wdio-qmate-service
Version:
[](https://api.reuse.software/info/github.com/SAP/wdio-qmate-service)[](http
152 lines • 5.91 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
class Decryption {
constructor() {
this.path = require("path");
this.fs = require("fs");
this.crypto = require("crypto");
this.childProcess = require("child_process");
}
initDecryptFunction() {
try {
const privateKey = this.retrievePrivateKey(this.path.resolve(__dirname, "../../../.."));
global.util.data.privateKeyFound = true;
global.util.data.decrypt = (input) => {
return this.decryptSecureData(privateKey, input);
};
}
catch (error) {
global.util.data.decrypt = function () {
throw new Error("Function 'decrypt' failed: No private key found.");
};
}
}
retrievePrivateKey(dirname) {
let privateKey;
try {
privateKey = this.fs.readFileSync(this.path.resolve(process.cwd(), "private.key"), "utf8");
}
catch (error) {
if (process.env.QMATE_PRIVATE_KEY) {
privateKey = process.env.QMATE_PRIVATE_KEY;
privateKey = privateKey.replace(/\\n/gm, "\n");
privateKey = privateKey.replace(/\\s/gm, " ");
}
else {
try {
privateKey = this.fs.readFileSync(this.path.resolve(dirname, "private.key"), "utf8");
}
catch (error) {
throw new Error(`No private key found: ${error}`);
}
}
}
process.env.QMATE_PRIVATE_KEY = "";
return privateKey;
}
decryptSecureData(privateKey, input, options) {
// input data can either be as single value or array of values for different keys
if (typeof input === "string") {
input = [input];
}
let decryptedDataByKey;
let decryptError;
for (const data of input) {
try {
const dataEncoded = options?.base64Input ? this._base64ToUtf8(data) : data;
const decryptedDataByRepoName = Buffer.from(this._decryptDataWithRepoName(Buffer.from(dataEncoded, "hex")), "base64");
decryptedDataByKey = this.crypto.privateDecrypt({
key: this._parseKeyByEncoding(privateKey),
padding: this.crypto.constants.RSA_PKCS1_OAEP_PADDING,
oaepHash: "sha256",
}, decryptedDataByRepoName);
}
catch (error) {
decryptError = error;
}
}
if (decryptedDataByKey) {
return options?.base64Output ? this._utf8ToBase64(decryptedDataByKey.toString()) : decryptedDataByKey.toString();
}
else {
throw new Error(`Function 'decrypt' failed: ${decryptError}`);
}
}
decryptSauceConfig(config) {
try {
config.user = util.data.decrypt(config.user);
}
catch (error) {
// do nothing, user was not encrypted
}
try {
config.key = util.data.decrypt(config.key);
}
catch (error) {
// do nothing, key was not encrypted
}
}
_decryptDataWithRepoName(data) {
let repoUrl;
try {
repoUrl = this.childProcess.execSync("git config --get remote.origin.url").toString();
}
catch (error) {
throw new Error("Please execute from a valid git repository.");
}
const repoUrlContractHashed = this._unifyRepoUrl(repoUrl);
const salt = "72hdh393987f0hdc";
const secretKey = this.crypto.pbkdf2Sync(repoUrlContractHashed, salt, 100000, 32, "sha512");
const iv = "203efccd80e94d9f";
const decipher = this.crypto.createDecipheriv("aes-256-cbc", secretKey, iv);
let decryptedData = decipher.update(data, "hex", "utf8");
decryptedData += decipher.final("utf8");
return decryptedData;
}
_unifyRepoUrl(url) {
const httpsRegex = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/gm;
const sshRegex = /git@.*:.*\/.*.git/gm;
if (url.match(httpsRegex)) {
return this._unifyHTTPUrl(url);
}
else if (url.match(sshRegex)) {
return this._unifySSHUrl(url);
}
else {
throw new Error("Repo url is not valid");
}
}
_unifySSHUrl(url) {
const [hostAndAccount, repo] = url.replace("git@", "").trim().split("/");
const [host, account] = hostAndAccount.split(":");
const repoTrimmed = repo.endsWith(".git") ? repo.slice(0, -4) : repo;
return this._hashHostAccountAndRepo(host, account, repoTrimmed);
}
_unifyHTTPUrl(url) {
const urlWithoutProtocol = url.replace(/((\bhttp\b)|(\bhttps\b)):\/\//, "").trim();
const [host, account, repo] = urlWithoutProtocol.split("/");
const repoTrimmed = repo.endsWith(".git") ? repo.slice(0, -4) : repo;
return this._hashHostAccountAndRepo(host, account, repoTrimmed);
}
_hashHostAccountAndRepo(host, account, repo) {
return this.crypto.createHash("sha256").update(`${host}${account}${repo}`).digest("hex");
}
_parseKeyByEncoding(key) {
const utf8Regex = /-*(BEGIN|END)\s\w*\s(PRIVATE|PUBLIC)\sKEY-*/gm;
if (utf8Regex.test(key)) {
return key;
}
else {
console.log("Key was processed in base64 format");
return this._base64ToUtf8(key);
}
}
_base64ToUtf8(string) {
return Buffer.from(string, "base64").toString("utf-8");
}
_utf8ToBase64(string) {
return Buffer.from(string, "utf-8").toString("base64");
}
}
exports.default = new Decryption();
//# sourceMappingURL=decryption.js.map