mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 22:28:15 +00:00
Fixed integrations & bulk update issue
This commit is contained in:
+152
-110
@@ -2,9 +2,11 @@ import crypto from "crypto";
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
IntegrationAuthsSchema,
|
||||||
SecretApprovalRequestsSecretsSchema,
|
SecretApprovalRequestsSecretsSchema,
|
||||||
SecretsSchema,
|
SecretsSchema,
|
||||||
SecretVersionsSchema,
|
SecretVersionsSchema,
|
||||||
|
TIntegrationAuths,
|
||||||
TProjectKeys,
|
TProjectKeys,
|
||||||
TSecretApprovalRequestsSecrets,
|
TSecretApprovalRequestsSecrets,
|
||||||
TSecrets,
|
TSecrets,
|
||||||
@@ -25,6 +27,16 @@ const DecryptedSecretSchema = z.object({
|
|||||||
original: SecretsSchema
|
original: SecretsSchema
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const DecryptedIntegrationAuthsSchema = z.object({
|
||||||
|
decrypted: z.object({
|
||||||
|
id: z.string(),
|
||||||
|
access: z.string(),
|
||||||
|
accessId: z.string(),
|
||||||
|
refresh: z.string()
|
||||||
|
}),
|
||||||
|
original: IntegrationAuthsSchema
|
||||||
|
});
|
||||||
|
|
||||||
const DecryptedSecretVersionsSchema = z.object({
|
const DecryptedSecretVersionsSchema = z.object({
|
||||||
decrypted: DecryptedValuesSchema,
|
decrypted: DecryptedValuesSchema,
|
||||||
original: SecretVersionsSchema
|
original: SecretVersionsSchema
|
||||||
@@ -38,6 +50,13 @@ export const DecryptedSecretApprovalsSchema = z.object({
|
|||||||
export type DecryptedSecret = z.infer<typeof DecryptedSecretSchema>;
|
export type DecryptedSecret = z.infer<typeof DecryptedSecretSchema>;
|
||||||
export type DecryptedSecretVersions = z.infer<typeof DecryptedSecretVersionsSchema>;
|
export type DecryptedSecretVersions = z.infer<typeof DecryptedSecretVersionsSchema>;
|
||||||
export type DecryptedSecretApprovals = z.infer<typeof DecryptedSecretApprovalsSchema>;
|
export type DecryptedSecretApprovals = z.infer<typeof DecryptedSecretApprovalsSchema>;
|
||||||
|
export type DecryptedIntegrationAuths = z.infer<typeof DecryptedIntegrationAuthsSchema>;
|
||||||
|
|
||||||
|
type TLatestKey = TProjectKeys & {
|
||||||
|
sender: {
|
||||||
|
publicKey: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const decryptCipher = ({
|
const decryptCipher = ({
|
||||||
ciphertext,
|
ciphertext,
|
||||||
@@ -59,69 +78,20 @@ const decryptCipher = ({
|
|||||||
return cleartext;
|
return cleartext;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getDecryptedValues = ({
|
const getDecryptedValues = (data: Array<{ ciphertext: string; iv: string; tag: string }>, key: string | Buffer) => {
|
||||||
secretKeyCiphertext,
|
const results = [];
|
||||||
secretKeyIV,
|
|
||||||
secretKeyTag,
|
|
||||||
secretValueCiphertext,
|
|
||||||
secretValueIV,
|
|
||||||
secretValueTag,
|
|
||||||
|
|
||||||
secretCommentCiphertext,
|
for (const { ciphertext, iv, tag } of data) {
|
||||||
secretCommentIV,
|
if (!ciphertext || !iv || !tag) {
|
||||||
secretCommentTag,
|
results.push("");
|
||||||
key
|
} else {
|
||||||
}: {
|
results.push(decryptCipher({ ciphertext, iv, tag, key }));
|
||||||
secretKeyCiphertext: string;
|
}
|
||||||
secretKeyIV: string;
|
|
||||||
secretKeyTag: string;
|
|
||||||
secretValueCiphertext: string;
|
|
||||||
secretValueIV: string;
|
|
||||||
secretValueTag: string;
|
|
||||||
secretCommentCiphertext?: string | null;
|
|
||||||
secretCommentIV?: string | null;
|
|
||||||
secretCommentTag?: string | null;
|
|
||||||
key: string | Buffer;
|
|
||||||
}) => {
|
|
||||||
const secretKey = decryptCipher({
|
|
||||||
ciphertext: secretKeyCiphertext,
|
|
||||||
iv: secretKeyIV,
|
|
||||||
tag: secretKeyTag,
|
|
||||||
key
|
|
||||||
});
|
|
||||||
|
|
||||||
const secretValue = decryptCipher({
|
|
||||||
ciphertext: secretValueCiphertext,
|
|
||||||
iv: secretValueIV,
|
|
||||||
tag: secretValueTag,
|
|
||||||
key
|
|
||||||
});
|
|
||||||
|
|
||||||
const secretComment =
|
|
||||||
secretCommentCiphertext && secretCommentIV && secretCommentTag
|
|
||||||
? decryptCipher({
|
|
||||||
ciphertext: secretCommentCiphertext,
|
|
||||||
iv: secretCommentIV,
|
|
||||||
tag: secretCommentTag,
|
|
||||||
key
|
|
||||||
})
|
|
||||||
: "";
|
|
||||||
|
|
||||||
return {
|
|
||||||
secretKey,
|
|
||||||
secretValue,
|
|
||||||
secretComment
|
|
||||||
};
|
|
||||||
};
|
|
||||||
export const decryptSecrets = (
|
|
||||||
encryptedSecrets: TSecrets[],
|
|
||||||
privateKey: string,
|
|
||||||
latestKey: TProjectKeys & {
|
|
||||||
sender: {
|
|
||||||
publicKey: string;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
) => {
|
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
export const decryptSecrets = (encryptedSecrets: TSecrets[], privateKey: string, latestKey: TLatestKey) => {
|
||||||
const key = decryptAsymmetric({
|
const key = decryptAsymmetric({
|
||||||
ciphertext: latestKey.encryptedKey,
|
ciphertext: latestKey.encryptedKey,
|
||||||
nonce: latestKey.nonce,
|
nonce: latestKey.nonce,
|
||||||
@@ -132,22 +102,32 @@ export const decryptSecrets = (
|
|||||||
const decryptedSecrets: DecryptedSecret[] = [];
|
const decryptedSecrets: DecryptedSecret[] = [];
|
||||||
|
|
||||||
encryptedSecrets.forEach((encSecret) => {
|
encryptedSecrets.forEach((encSecret) => {
|
||||||
const decrypted = getDecryptedValues({
|
const [secretKey, secretValue, secretComment] = getDecryptedValues(
|
||||||
secretKeyCiphertext: encSecret.secretKeyCiphertext,
|
[
|
||||||
secretKeyIV: encSecret.secretKeyIV,
|
{
|
||||||
secretKeyTag: encSecret.secretKeyTag,
|
ciphertext: encSecret.secretKeyCiphertext,
|
||||||
secretValueCiphertext: encSecret.secretValueCiphertext,
|
iv: encSecret.secretKeyIV,
|
||||||
secretValueIV: encSecret.secretValueIV,
|
tag: encSecret.secretKeyTag
|
||||||
secretValueTag: encSecret.secretValueTag,
|
},
|
||||||
secretCommentCiphertext: encSecret.secretCommentCiphertext,
|
{
|
||||||
secretCommentIV: encSecret.secretCommentIV,
|
ciphertext: encSecret.secretValueCiphertext,
|
||||||
secretCommentTag: encSecret.secretCommentTag,
|
iv: encSecret.secretValueIV,
|
||||||
|
tag: encSecret.secretValueTag
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ciphertext: encSecret.secretCommentCiphertext || "",
|
||||||
|
iv: encSecret.secretCommentIV || "",
|
||||||
|
tag: encSecret.secretCommentTag || ""
|
||||||
|
}
|
||||||
|
],
|
||||||
key
|
key
|
||||||
});
|
);
|
||||||
|
|
||||||
const decryptedSecret: DecryptedSecret = {
|
const decryptedSecret: DecryptedSecret = {
|
||||||
decrypted: {
|
decrypted: {
|
||||||
...decrypted,
|
secretKey,
|
||||||
|
secretValue,
|
||||||
|
secretComment,
|
||||||
id: encSecret.id
|
id: encSecret.id
|
||||||
},
|
},
|
||||||
original: encSecret
|
original: encSecret
|
||||||
@@ -162,11 +142,7 @@ export const decryptSecrets = (
|
|||||||
export const decryptSecretVersions = (
|
export const decryptSecretVersions = (
|
||||||
encryptedSecretVersions: TSecretVersions[],
|
encryptedSecretVersions: TSecretVersions[],
|
||||||
privateKey: string,
|
privateKey: string,
|
||||||
latestKey: TProjectKeys & {
|
latestKey: TLatestKey
|
||||||
sender: {
|
|
||||||
publicKey: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
) => {
|
) => {
|
||||||
const key = decryptAsymmetric({
|
const key = decryptAsymmetric({
|
||||||
ciphertext: latestKey.encryptedKey,
|
ciphertext: latestKey.encryptedKey,
|
||||||
@@ -178,22 +154,32 @@ export const decryptSecretVersions = (
|
|||||||
const decryptedSecrets: DecryptedSecretVersions[] = [];
|
const decryptedSecrets: DecryptedSecretVersions[] = [];
|
||||||
|
|
||||||
encryptedSecretVersions.forEach((encSecret) => {
|
encryptedSecretVersions.forEach((encSecret) => {
|
||||||
const decrypted = getDecryptedValues({
|
const [secretKey, secretValue, secretComment] = getDecryptedValues(
|
||||||
secretKeyCiphertext: encSecret.secretKeyCiphertext,
|
[
|
||||||
secretKeyIV: encSecret.secretKeyIV,
|
{
|
||||||
secretKeyTag: encSecret.secretKeyTag,
|
ciphertext: encSecret.secretKeyCiphertext,
|
||||||
secretValueCiphertext: encSecret.secretValueCiphertext,
|
iv: encSecret.secretKeyIV,
|
||||||
secretValueIV: encSecret.secretValueIV,
|
tag: encSecret.secretKeyTag
|
||||||
secretValueTag: encSecret.secretValueTag,
|
},
|
||||||
secretCommentCiphertext: encSecret.secretCommentCiphertext,
|
{
|
||||||
secretCommentIV: encSecret.secretCommentIV,
|
ciphertext: encSecret.secretValueCiphertext,
|
||||||
secretCommentTag: encSecret.secretCommentTag,
|
iv: encSecret.secretValueIV,
|
||||||
|
tag: encSecret.secretValueTag
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ciphertext: encSecret.secretCommentCiphertext || "",
|
||||||
|
iv: encSecret.secretCommentIV || "",
|
||||||
|
tag: encSecret.secretCommentTag || ""
|
||||||
|
}
|
||||||
|
],
|
||||||
key
|
key
|
||||||
});
|
);
|
||||||
|
|
||||||
const decryptedSecret: DecryptedSecretVersions = {
|
const decryptedSecret: DecryptedSecretVersions = {
|
||||||
decrypted: {
|
decrypted: {
|
||||||
...decrypted,
|
secretKey,
|
||||||
|
secretValue,
|
||||||
|
secretComment,
|
||||||
id: encSecret.id
|
id: encSecret.id
|
||||||
},
|
},
|
||||||
original: encSecret
|
original: encSecret
|
||||||
@@ -208,11 +194,7 @@ export const decryptSecretVersions = (
|
|||||||
export const decryptSecretApprovals = (
|
export const decryptSecretApprovals = (
|
||||||
encryptedSecretApprovals: TSecretApprovalRequestsSecrets[],
|
encryptedSecretApprovals: TSecretApprovalRequestsSecrets[],
|
||||||
privateKey: string,
|
privateKey: string,
|
||||||
latestKey: TProjectKeys & {
|
latestKey: TLatestKey
|
||||||
sender: {
|
|
||||||
publicKey: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
) => {
|
) => {
|
||||||
const key = decryptAsymmetric({
|
const key = decryptAsymmetric({
|
||||||
ciphertext: latestKey.encryptedKey,
|
ciphertext: latestKey.encryptedKey,
|
||||||
@@ -223,26 +205,36 @@ export const decryptSecretApprovals = (
|
|||||||
|
|
||||||
const decryptedSecrets: DecryptedSecretApprovals[] = [];
|
const decryptedSecrets: DecryptedSecretApprovals[] = [];
|
||||||
|
|
||||||
encryptedSecretApprovals.forEach((encSecret) => {
|
encryptedSecretApprovals.forEach((encApproval) => {
|
||||||
const decrypted = getDecryptedValues({
|
const [secretKey, secretValue, secretComment] = getDecryptedValues(
|
||||||
secretKeyCiphertext: encSecret.secretKeyCiphertext,
|
[
|
||||||
secretKeyIV: encSecret.secretKeyIV,
|
{
|
||||||
secretKeyTag: encSecret.secretKeyTag,
|
ciphertext: encApproval.secretKeyCiphertext,
|
||||||
secretValueCiphertext: encSecret.secretValueCiphertext,
|
iv: encApproval.secretKeyIV,
|
||||||
secretValueIV: encSecret.secretValueIV,
|
tag: encApproval.secretKeyTag
|
||||||
secretValueTag: encSecret.secretValueTag,
|
},
|
||||||
secretCommentCiphertext: encSecret.secretCommentCiphertext,
|
{
|
||||||
secretCommentIV: encSecret.secretCommentIV,
|
ciphertext: encApproval.secretValueCiphertext,
|
||||||
secretCommentTag: encSecret.secretCommentTag,
|
iv: encApproval.secretValueIV,
|
||||||
|
tag: encApproval.secretValueTag
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ciphertext: encApproval.secretCommentCiphertext || "",
|
||||||
|
iv: encApproval.secretCommentIV || "",
|
||||||
|
tag: encApproval.secretCommentTag || ""
|
||||||
|
}
|
||||||
|
],
|
||||||
key
|
key
|
||||||
});
|
);
|
||||||
|
|
||||||
const decryptedSecret: DecryptedSecretApprovals = {
|
const decryptedSecret: DecryptedSecretApprovals = {
|
||||||
decrypted: {
|
decrypted: {
|
||||||
...decrypted,
|
secretKey,
|
||||||
id: encSecret.id
|
secretValue,
|
||||||
|
secretComment,
|
||||||
|
id: encApproval.id
|
||||||
},
|
},
|
||||||
original: encSecret
|
original: encApproval
|
||||||
};
|
};
|
||||||
|
|
||||||
decryptedSecrets.push(DecryptedSecretApprovalsSchema.parse(decryptedSecret));
|
decryptedSecrets.push(DecryptedSecretApprovalsSchema.parse(decryptedSecret));
|
||||||
@@ -250,3 +242,53 @@ export const decryptSecretApprovals = (
|
|||||||
|
|
||||||
return decryptedSecrets;
|
return decryptedSecrets;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const decryptIntegrationAuths = (
|
||||||
|
encryptedIntegrationAuths: TIntegrationAuths[],
|
||||||
|
privateKey: string,
|
||||||
|
latestKey: TLatestKey
|
||||||
|
) => {
|
||||||
|
const key = decryptAsymmetric({
|
||||||
|
ciphertext: latestKey.encryptedKey,
|
||||||
|
nonce: latestKey.nonce,
|
||||||
|
publicKey: latestKey.sender.publicKey,
|
||||||
|
privateKey
|
||||||
|
});
|
||||||
|
|
||||||
|
const decryptedIntegrationAuths: DecryptedIntegrationAuths[] = [];
|
||||||
|
|
||||||
|
encryptedIntegrationAuths.forEach((encAuth) => {
|
||||||
|
const [access, accessId, refresh] = getDecryptedValues(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
ciphertext: encAuth.accessCiphertext || "",
|
||||||
|
iv: encAuth.accessIV || "",
|
||||||
|
tag: encAuth.accessTag || ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ciphertext: encAuth.accessIdCiphertext || "",
|
||||||
|
iv: encAuth.accessIdIV || "",
|
||||||
|
tag: encAuth.accessIdTag || ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ciphertext: encAuth.refreshCiphertext || "",
|
||||||
|
iv: encAuth.refreshIV || "",
|
||||||
|
tag: encAuth.refreshTag || ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
key
|
||||||
|
);
|
||||||
|
|
||||||
|
decryptedIntegrationAuths.push({
|
||||||
|
decrypted: {
|
||||||
|
id: encAuth.id,
|
||||||
|
access,
|
||||||
|
accessId,
|
||||||
|
refresh
|
||||||
|
},
|
||||||
|
original: encAuth
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return decryptedIntegrationAuths;
|
||||||
|
};
|
||||||
|
|||||||
@@ -178,6 +178,10 @@ export const projectQueueFactory = ({
|
|||||||
approvalSecrets.push(...secretApprovals);
|
approvalSecrets.push(...secretApprovals);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const projectIntegrationAuths = await integrationAuthDAL.find({
|
||||||
|
projectId: project.id
|
||||||
|
});
|
||||||
|
|
||||||
const decryptedSecrets = decryptSecrets(secrets, userPrivateKey, oldProjectKey);
|
const decryptedSecrets = decryptSecrets(secrets, userPrivateKey, oldProjectKey);
|
||||||
const decryptedSecretVersions = decryptSecretVersions(secretVersions, userPrivateKey, oldProjectKey);
|
const decryptedSecretVersions = decryptSecretVersions(secretVersions, userPrivateKey, oldProjectKey);
|
||||||
const decryptedApprovalSecrets = decryptSecretApprovals(approvalSecrets, userPrivateKey, oldProjectKey);
|
const decryptedApprovalSecrets = decryptSecretApprovals(approvalSecrets, userPrivateKey, oldProjectKey);
|
||||||
@@ -504,21 +508,6 @@ export const projectQueueFactory = ({
|
|||||||
throw new Error("Parts of the upgrade failed. Some secrets were not updated");
|
throw new Error("Parts of the upgrade failed. Some secrets were not updated");
|
||||||
}
|
}
|
||||||
|
|
||||||
const secretUpdates = await secretDAL.bulkUpdateNoVersionIncrement(updatedSecrets, tx);
|
|
||||||
const secretVersionUpdates = await secretVersionDAL.bulkUpdateNoVersionIncrement(updatedSecretVersions, tx);
|
|
||||||
const secretApprovalUpdates = await secretApprovalSecretDAL.bulkUpdateNoVersionIncrement(
|
|
||||||
updatedSecretApprovals,
|
|
||||||
tx
|
|
||||||
);
|
|
||||||
|
|
||||||
if (
|
|
||||||
secretUpdates.length !== updatedSecrets.length ||
|
|
||||||
secretVersionUpdates.length !== updatedSecretVersions.length ||
|
|
||||||
secretApprovalUpdates.length !== updatedSecretApprovals.length
|
|
||||||
) {
|
|
||||||
throw new Error("Parts of the upgrade failed. Some secrets were not updated");
|
|
||||||
}
|
|
||||||
|
|
||||||
await projectDAL.setProjectUpgradeStatus(data.projectId, null, tx);
|
await projectDAL.setProjectUpgradeStatus(data.projectId, null, tx);
|
||||||
|
|
||||||
// await new Promise((resolve) => setTimeout(resolve, 15_000));
|
// await new Promise((resolve) => setTimeout(resolve, 15_000));
|
||||||
|
|||||||
Reference in New Issue
Block a user