mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 15:28:25 +00:00
feat: updated backward compatiable enc key
This commit is contained in:
@@ -6,7 +6,11 @@ import { getWebhookPayload, triggerWebhookRequest } from "../../services/Webhook
|
|||||||
import { BadRequestError, ResourceNotFoundError } from "../../utils/errors";
|
import { BadRequestError, ResourceNotFoundError } from "../../utils/errors";
|
||||||
import { EEAuditLogService } from "../../ee/services";
|
import { EEAuditLogService } from "../../ee/services";
|
||||||
import { EventType } from "../../ee/models";
|
import { EventType } from "../../ee/models";
|
||||||
import { ALGORITHM_AES_256_GCM, ENCODING_SCHEME_BASE64 } from "../../variables";
|
import {
|
||||||
|
ALGORITHM_AES_256_GCM,
|
||||||
|
ENCODING_SCHEME_BASE64,
|
||||||
|
ENCODING_SCHEME_UTF8
|
||||||
|
} from "../../variables";
|
||||||
import { validateRequest } from "../../helpers/validation";
|
import { validateRequest } from "../../helpers/validation";
|
||||||
import * as reqValidator from "../../validation/webhooks";
|
import * as reqValidator from "../../validation/webhooks";
|
||||||
import {
|
import {
|
||||||
@@ -15,6 +19,7 @@ import {
|
|||||||
getUserProjectPermissions
|
getUserProjectPermissions
|
||||||
} from "../../ee/services/ProjectRoleService";
|
} from "../../ee/services/ProjectRoleService";
|
||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
|
import { encryptSymmetric128BitHexKeyUTF8 } from "../../utils/crypto";
|
||||||
|
|
||||||
export const createWebhook = async (req: Request, res: Response) => {
|
export const createWebhook = async (req: Request, res: Response) => {
|
||||||
const {
|
const {
|
||||||
@@ -31,20 +36,31 @@ export const createWebhook = async (req: Request, res: Response) => {
|
|||||||
workspace: workspaceId,
|
workspace: workspaceId,
|
||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
url: webhookUrl,
|
url: webhookUrl
|
||||||
algorithm: ALGORITHM_AES_256_GCM,
|
|
||||||
keyEncoding: ENCODING_SCHEME_BASE64
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (webhookSecretKey) {
|
if (webhookSecretKey) {
|
||||||
let encryptionKey = await getRootEncryptionKey();
|
const encryptionKey = await getEncryptionKey();
|
||||||
if (!encryptionKey) {
|
const rootEncryptionKey = await getRootEncryptionKey();
|
||||||
encryptionKey = await getEncryptionKey();
|
|
||||||
|
if (rootEncryptionKey) {
|
||||||
|
const { ciphertext, iv, tag } = client.encryptSymmetric(webhookSecretKey, rootEncryptionKey);
|
||||||
|
webhook.iv = iv;
|
||||||
|
webhook.tag = tag;
|
||||||
|
webhook.encryptedSecretKey = ciphertext;
|
||||||
|
webhook.algorithm = ALGORITHM_AES_256_GCM;
|
||||||
|
webhook.keyEncoding = ENCODING_SCHEME_BASE64;
|
||||||
|
} else if (encryptionKey) {
|
||||||
|
const { ciphertext, iv, tag } = encryptSymmetric128BitHexKeyUTF8({
|
||||||
|
plaintext: webhookSecretKey,
|
||||||
|
key: encryptionKey
|
||||||
|
});
|
||||||
|
webhook.iv = iv;
|
||||||
|
webhook.tag = tag;
|
||||||
|
webhook.encryptedSecretKey = ciphertext;
|
||||||
|
webhook.algorithm = ALGORITHM_AES_256_GCM;
|
||||||
|
webhook.keyEncoding = ENCODING_SCHEME_UTF8;
|
||||||
}
|
}
|
||||||
const { ciphertext, iv, tag } = client.encryptSymmetric(webhookSecretKey, encryptionKey);
|
|
||||||
webhook.iv = iv;
|
|
||||||
webhook.tag = tag;
|
|
||||||
webhook.encryptedSecretKey = ciphertext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await webhook.save();
|
await webhook.save();
|
||||||
|
|||||||
@@ -65,13 +65,11 @@ const WebhookSchema = new Schema<IWebhook>(
|
|||||||
// the encryption algorithm used
|
// the encryption algorithm used
|
||||||
type: String,
|
type: String,
|
||||||
enum: [ALGORITHM_AES_256_GCM],
|
enum: [ALGORITHM_AES_256_GCM],
|
||||||
required: true,
|
|
||||||
select: false
|
select: false
|
||||||
},
|
},
|
||||||
keyEncoding: {
|
keyEncoding: {
|
||||||
type: String,
|
type: String,
|
||||||
enum: [ENCODING_SCHEME_UTF8, ENCODING_SCHEME_BASE64],
|
enum: [ENCODING_SCHEME_UTF8, ENCODING_SCHEME_BASE64],
|
||||||
required: true,
|
|
||||||
select: false
|
select: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,26 +2,42 @@ import axios from "axios";
|
|||||||
import crypto from "crypto";
|
import crypto from "crypto";
|
||||||
import { Types } from "mongoose";
|
import { Types } from "mongoose";
|
||||||
import picomatch from "picomatch";
|
import picomatch from "picomatch";
|
||||||
import { client, getRootEncryptionKey } from "../config";
|
import { client, getEncryptionKey, getRootEncryptionKey } from "../config";
|
||||||
import { IWebhook, Webhook } from "../models";
|
import { IWebhook, Webhook } from "../models";
|
||||||
|
import { decryptSymmetric128BitHexKeyUTF8 } from "../utils/crypto";
|
||||||
|
import { ENCODING_SCHEME_BASE64, ENCODING_SCHEME_UTF8 } from "../variables";
|
||||||
|
|
||||||
export const triggerWebhookRequest = async (
|
export const triggerWebhookRequest = async (
|
||||||
{ url, encryptedSecretKey, iv, tag }: IWebhook,
|
{ url, encryptedSecretKey, iv, tag, keyEncoding }: IWebhook,
|
||||||
payload: Record<string, unknown>
|
payload: Record<string, unknown>
|
||||||
) => {
|
) => {
|
||||||
const headers: Record<string, string> = {};
|
const headers: Record<string, string> = {};
|
||||||
payload["timestamp"] = Date.now();
|
payload["timestamp"] = Date.now();
|
||||||
|
|
||||||
if (encryptedSecretKey) {
|
if (encryptedSecretKey) {
|
||||||
|
const encryptionKey = await getEncryptionKey();
|
||||||
const rootEncryptionKey = await getRootEncryptionKey();
|
const rootEncryptionKey = await getRootEncryptionKey();
|
||||||
const secretKey = client.decryptSymmetric(encryptedSecretKey, rootEncryptionKey, iv, tag);
|
let secretKey;
|
||||||
const webhookSign = crypto
|
if (rootEncryptionKey && keyEncoding === ENCODING_SCHEME_BASE64) {
|
||||||
.createHmac("sha256", secretKey)
|
// case: encoding scheme is base64
|
||||||
.update(JSON.stringify(payload))
|
secretKey = client.decryptSymmetric(encryptedSecretKey, rootEncryptionKey, iv, tag);
|
||||||
.digest("hex");
|
} else if (encryptionKey && keyEncoding === ENCODING_SCHEME_UTF8) {
|
||||||
headers["x-infisical-signature"] = `t=${payload["timestamp"]};${webhookSign}`;
|
// case: encoding scheme is utf8
|
||||||
|
secretKey = decryptSymmetric128BitHexKeyUTF8({
|
||||||
|
ciphertext: encryptedSecretKey,
|
||||||
|
iv: iv,
|
||||||
|
tag: tag,
|
||||||
|
key: encryptionKey
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (secretKey) {
|
||||||
|
const webhookSign = crypto
|
||||||
|
.createHmac("sha256", secretKey)
|
||||||
|
.update(JSON.stringify(payload))
|
||||||
|
.digest("hex");
|
||||||
|
headers["x-infisical-signature"] = `t=${payload["timestamp"]};${webhookSign}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const req = await axios.post(url, payload, { headers });
|
const req = await axios.post(url, payload, { headers });
|
||||||
return req;
|
return req;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user