mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 12:27:28 +00:00
Merge pull request #4574 from Infisical/secret-update-request-fixes
fix(secret-change-requests): various UPDATE change request fixes
This commit is contained in:
+19
@@ -0,0 +1,19 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "@app/db/schemas";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
if (await knex.schema.hasTable(TableName.SecretApprovalRequestSecretV2)) {
|
||||||
|
await knex.schema.alterTable(TableName.SecretApprovalRequestSecretV2, (t) => {
|
||||||
|
t.boolean("skipMultilineEncoding").alter();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function down(knex: Knex): Promise<void> {
|
||||||
|
if (await knex.schema.hasTable(TableName.SecretApprovalRequestSecretV2)) {
|
||||||
|
await knex.schema.alterTable(TableName.SecretApprovalRequestSecretV2, (t) => {
|
||||||
|
t.boolean("skipMultilineEncoding").defaultTo(false).alter();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ export const SecretApprovalRequestsSecretsV2Schema = z.object({
|
|||||||
encryptedComment: zodBuffer.nullable().optional(),
|
encryptedComment: zodBuffer.nullable().optional(),
|
||||||
reminderNote: z.string().nullable().optional(),
|
reminderNote: z.string().nullable().optional(),
|
||||||
reminderRepeatDays: z.number().nullable().optional(),
|
reminderRepeatDays: z.number().nullable().optional(),
|
||||||
skipMultilineEncoding: z.boolean().default(false).nullable().optional(),
|
skipMultilineEncoding: z.boolean().nullable().optional(),
|
||||||
metadata: z.unknown().nullable().optional(),
|
metadata: z.unknown().nullable().optional(),
|
||||||
createdAt: z.date(),
|
createdAt: z.date(),
|
||||||
updatedAt: z.date(),
|
updatedAt: z.date(),
|
||||||
|
|||||||
@@ -320,10 +320,20 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
|||||||
.array(),
|
.array(),
|
||||||
secretPath: z.string(),
|
secretPath: z.string(),
|
||||||
commits: secretRawSchema
|
commits: secretRawSchema
|
||||||
.omit({ _id: true, environment: true, workspace: true, type: true, version: true, secretValue: true })
|
.omit({
|
||||||
|
_id: true,
|
||||||
|
environment: true,
|
||||||
|
workspace: true,
|
||||||
|
type: true,
|
||||||
|
version: true,
|
||||||
|
secretValue: true,
|
||||||
|
secretComment: true
|
||||||
|
})
|
||||||
.extend({
|
.extend({
|
||||||
secretValueHidden: z.boolean(),
|
secretValueHidden: z.boolean(),
|
||||||
secretValue: z.string().optional(),
|
secretValue: z.string().optional(),
|
||||||
|
secretComment: z.string().optional(),
|
||||||
|
skipMultilineEncoding: z.boolean().nullish(),
|
||||||
isRotatedSecret: z.boolean().optional(),
|
isRotatedSecret: z.boolean().optional(),
|
||||||
op: z.string(),
|
op: z.string(),
|
||||||
tags: SanitizedTagSchema.array().optional(),
|
tags: SanitizedTagSchema.array().optional(),
|
||||||
@@ -348,7 +358,8 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
|||||||
secretValueHidden: z.boolean(),
|
secretValueHidden: z.boolean(),
|
||||||
secretComment: z.string().optional(),
|
secretComment: z.string().optional(),
|
||||||
tags: SanitizedTagSchema.array().optional(),
|
tags: SanitizedTagSchema.array().optional(),
|
||||||
secretMetadata: ResourceMetadataSchema.nullish()
|
secretMetadata: ResourceMetadataSchema.nullish(),
|
||||||
|
skipMultilineEncoding: z.boolean().nullish()
|
||||||
})
|
})
|
||||||
.optional()
|
.optional()
|
||||||
})
|
})
|
||||||
|
|||||||
+12
-3
@@ -284,7 +284,8 @@ export const secretApprovalRequestSecretDALFactory = (db: TDbClient) => {
|
|||||||
db.ref("version").withSchema(TableName.SecretVersionV2).as("secVerVersion"),
|
db.ref("version").withSchema(TableName.SecretVersionV2).as("secVerVersion"),
|
||||||
db.ref("key").withSchema(TableName.SecretVersionV2).as("secVerKey"),
|
db.ref("key").withSchema(TableName.SecretVersionV2).as("secVerKey"),
|
||||||
db.ref("encryptedValue").withSchema(TableName.SecretVersionV2).as("secVerValue"),
|
db.ref("encryptedValue").withSchema(TableName.SecretVersionV2).as("secVerValue"),
|
||||||
db.ref("encryptedComment").withSchema(TableName.SecretVersionV2).as("secVerComment")
|
db.ref("encryptedComment").withSchema(TableName.SecretVersionV2).as("secVerComment"),
|
||||||
|
db.ref("skipMultilineEncoding").withSchema(TableName.SecretVersionV2).as("secVerSkipMultilineEncoding")
|
||||||
)
|
)
|
||||||
.select(
|
.select(
|
||||||
db.ref("id").withSchema(TableName.ResourceMetadata).as("metadataId"),
|
db.ref("id").withSchema(TableName.ResourceMetadata).as("metadataId"),
|
||||||
@@ -326,14 +327,22 @@ export const secretApprovalRequestSecretDALFactory = (db: TDbClient) => {
|
|||||||
{
|
{
|
||||||
key: "secretVersion",
|
key: "secretVersion",
|
||||||
label: "secretVersion" as const,
|
label: "secretVersion" as const,
|
||||||
mapper: ({ secretVersion, secVerVersion, secVerKey, secVerValue, secVerComment }) =>
|
mapper: ({
|
||||||
|
secretVersion,
|
||||||
|
secVerVersion,
|
||||||
|
secVerKey,
|
||||||
|
secVerValue,
|
||||||
|
secVerComment,
|
||||||
|
secVerSkipMultilineEncoding
|
||||||
|
}) =>
|
||||||
secretVersion
|
secretVersion
|
||||||
? {
|
? {
|
||||||
version: secVerVersion,
|
version: secVerVersion,
|
||||||
id: secretVersion,
|
id: secretVersion,
|
||||||
key: secVerKey,
|
key: secVerKey,
|
||||||
encryptedValue: secVerValue,
|
encryptedValue: secVerValue,
|
||||||
encryptedComment: secVerComment
|
encryptedComment: secVerComment,
|
||||||
|
skipMultilineEncoding: secVerSkipMultilineEncoding
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
childrenMapper: [
|
childrenMapper: [
|
||||||
|
|||||||
+19
-11
@@ -337,12 +337,17 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
? INFISICAL_SECRET_VALUE_HIDDEN_MASK
|
? INFISICAL_SECRET_VALUE_HIDDEN_MASK
|
||||||
: el.secret && el.secret.isRotatedSecret
|
: el.secret && el.secret.isRotatedSecret
|
||||||
? undefined
|
? undefined
|
||||||
: el.encryptedValue
|
: el.encryptedValue !== undefined && el.encryptedValue !== null
|
||||||
? secretManagerDecryptor({ cipherTextBlob: el.encryptedValue }).toString()
|
? secretManagerDecryptor({ cipherTextBlob: el.encryptedValue }).toString()
|
||||||
: "",
|
: undefined,
|
||||||
secretComment: el.encryptedComment
|
secretComment:
|
||||||
|
el.encryptedComment !== undefined && el.encryptedComment !== null
|
||||||
? secretManagerDecryptor({ cipherTextBlob: el.encryptedComment }).toString()
|
? secretManagerDecryptor({ cipherTextBlob: el.encryptedComment }).toString()
|
||||||
: "",
|
: undefined,
|
||||||
|
skipMultilineEncoding:
|
||||||
|
el.skipMultilineEncoding !== undefined && el.skipMultilineEncoding !== null
|
||||||
|
? el.skipMultilineEncoding
|
||||||
|
: undefined,
|
||||||
secret: el.secret
|
secret: el.secret
|
||||||
? {
|
? {
|
||||||
secretKey: el.secret.key,
|
secretKey: el.secret.key,
|
||||||
@@ -394,7 +399,8 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
? secretManagerDecryptor({ cipherTextBlob: el.secretVersion.encryptedComment }).toString()
|
? secretManagerDecryptor({ cipherTextBlob: el.secretVersion.encryptedComment }).toString()
|
||||||
: "",
|
: "",
|
||||||
tags: el.secretVersion.tags,
|
tags: el.secretVersion.tags,
|
||||||
secretMetadata: el.oldSecretMetadata as ResourceMetadataDTO
|
secretMetadata: el.oldSecretMetadata as ResourceMetadataDTO,
|
||||||
|
skipMultilineEncoding: el.secretVersion.skipMultilineEncoding
|
||||||
}
|
}
|
||||||
: undefined
|
: undefined
|
||||||
}));
|
}));
|
||||||
@@ -733,9 +739,9 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
tx,
|
tx,
|
||||||
inputSecrets: secretUpdationCommits.map((el) => {
|
inputSecrets: secretUpdationCommits.map((el) => {
|
||||||
const encryptedValue =
|
const encryptedValue =
|
||||||
!el.secret?.isRotatedSecret && typeof el.encryptedValue !== "undefined"
|
!el.secret?.isRotatedSecret && el.encryptedValue !== null && el.encryptedValue !== undefined
|
||||||
? {
|
? {
|
||||||
encryptedValue: el.encryptedValue as Buffer,
|
encryptedValue: el.encryptedValue,
|
||||||
references: el.encryptedValue
|
references: el.encryptedValue
|
||||||
? getAllSecretReferencesV2Bridge(
|
? getAllSecretReferencesV2Bridge(
|
||||||
secretManagerDecryptor({
|
secretManagerDecryptor({
|
||||||
@@ -749,9 +755,9 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
filter: { id: el.secretId as string, type: SecretType.Shared },
|
filter: { id: el.secretId as string, type: SecretType.Shared },
|
||||||
data: {
|
data: {
|
||||||
reminderRepeatDays: el.reminderRepeatDays,
|
reminderRepeatDays: el.reminderRepeatDays,
|
||||||
encryptedComment: el.encryptedComment,
|
encryptedComment: el.encryptedComment !== null ? el.encryptedComment : undefined,
|
||||||
reminderNote: el.reminderNote,
|
reminderNote: el.reminderNote,
|
||||||
skipMultilineEncoding: el.skipMultilineEncoding,
|
skipMultilineEncoding: el.skipMultilineEncoding !== null ? el.skipMultilineEncoding : undefined,
|
||||||
key: el.key,
|
key: el.key,
|
||||||
tags: el?.tags.map(({ id }) => id),
|
tags: el?.tags.map(({ id }) => id),
|
||||||
secretMetadata: el.secretMetadata as ResourceMetadataDTO,
|
secretMetadata: el.secretMetadata as ResourceMetadataDTO,
|
||||||
@@ -1633,11 +1639,13 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
key: newSecretName || secretKey,
|
key: newSecretName || secretKey,
|
||||||
encryptedComment: setKnexStringValue(
|
encryptedComment: setKnexStringValue(
|
||||||
secretComment,
|
secretComment,
|
||||||
(value) => secretManagerEncryptor({ plainText: Buffer.from(value) }).cipherTextBlob
|
(value) => secretManagerEncryptor({ plainText: Buffer.from(value) }).cipherTextBlob,
|
||||||
|
true // scott: we need to encrypt empty string on update to differentiate not updating comment vs clearing comment
|
||||||
),
|
),
|
||||||
encryptedValue: setKnexStringValue(
|
encryptedValue: setKnexStringValue(
|
||||||
secretValue,
|
secretValue,
|
||||||
(value) => secretManagerEncryptor({ plainText: Buffer.from(value) }).cipherTextBlob
|
(value) => secretManagerEncryptor({ plainText: Buffer.from(value) }).cipherTextBlob,
|
||||||
|
true // scott: we need to encrypt empty string on update to differentiate not updating value vs clearing value
|
||||||
),
|
),
|
||||||
reminderRepeatDays,
|
reminderRepeatDays,
|
||||||
reminderNote,
|
reminderNote,
|
||||||
|
|||||||
@@ -16,8 +16,12 @@ export const stripUndefinedInWhere = <T extends object>(val: T): Exclude<T, unde
|
|||||||
// if its undefined its skipped in knex
|
// if its undefined its skipped in knex
|
||||||
// if its empty string its set as null
|
// if its empty string its set as null
|
||||||
// else pass to the required one
|
// else pass to the required one
|
||||||
export const setKnexStringValue = <T>(value: string | null | undefined, cb: (arg: string) => T) => {
|
export const setKnexStringValue = <T>(
|
||||||
|
value: string | null | undefined,
|
||||||
|
cb: (arg: string) => T,
|
||||||
|
allowEmptyString?: boolean
|
||||||
|
) => {
|
||||||
if (typeof value === "undefined") return;
|
if (typeof value === "undefined") return;
|
||||||
if (value === "" || value === null) return null;
|
if ((value === "" && !allowEmptyString) || value === null) return null;
|
||||||
return cb(value);
|
return cb(value);
|
||||||
};
|
};
|
||||||
|
|||||||
-1
@@ -113,7 +113,6 @@ function SecretRenameRow({ environments, getSecretByKey, secretKey, secretPath }
|
|||||||
projectId,
|
projectId,
|
||||||
secretPath,
|
secretPath,
|
||||||
secretKey: secret.key,
|
secretKey: secret.key,
|
||||||
secretValue: secret.value || "",
|
|
||||||
type: SecretType.Shared,
|
type: SecretType.Shared,
|
||||||
tagIds: secret.tags?.map((tag) => tag.id),
|
tagIds: secret.tags?.map((tag) => tag.id),
|
||||||
secretComment: secret.comment,
|
secretComment: secret.comment,
|
||||||
|
|||||||
+22
-4
@@ -23,6 +23,7 @@ export type Props = {
|
|||||||
newVersion?: Omit<TSecretApprovalSecChange, "tags"> & {
|
newVersion?: Omit<TSecretApprovalSecChange, "tags"> & {
|
||||||
tags?: WsTag[];
|
tags?: WsTag[];
|
||||||
secretMetadata?: { key: string; value: string }[];
|
secretMetadata?: { key: string; value: string }[];
|
||||||
|
skipMultilineEncoding?: boolean;
|
||||||
};
|
};
|
||||||
presentSecretVersionNumber: number;
|
presentSecretVersionNumber: number;
|
||||||
hasMerged?: boolean;
|
hasMerged?: boolean;
|
||||||
@@ -217,6 +218,14 @@ export const SecretApprovalRequestChangeItem = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="mb-2">
|
||||||
|
<div className="text-sm font-medium text-mineshaft-300">Multi-line Encoding</div>
|
||||||
|
<div className="text-sm">
|
||||||
|
{secretVersion?.skipMultilineEncoding?.toString() || (
|
||||||
|
<span className="text-sm text-mineshaft-300">-</span>
|
||||||
|
)}{" "}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="text-md flex w-full items-center justify-center rounded-md border border-mineshaft-600 bg-mineshaft-800 text-mineshaft-300 xl:w-1/2">
|
<div className="text-md flex w-full items-center justify-center rounded-md border border-mineshaft-600 bg-mineshaft-800 text-mineshaft-300 xl:w-1/2">
|
||||||
@@ -263,7 +272,7 @@ export const SecretApprovalRequestChangeItem = ({
|
|||||||
isReadOnly
|
isReadOnly
|
||||||
valueAlwaysHidden={newVersion?.secretValueHidden}
|
valueAlwaysHidden={newVersion?.secretValueHidden}
|
||||||
isVisible={isNewSecretValueVisible}
|
isVisible={isNewSecretValueVisible}
|
||||||
value={newVersion?.secretValue}
|
value={newVersion?.secretValue ?? secretVersion?.secretValue}
|
||||||
containerClassName={twMerge(
|
containerClassName={twMerge(
|
||||||
"border border-mineshaft-600 bg-bunker-700 py-1.5 text-bunker-300 hover:border-primary-400/50",
|
"border border-mineshaft-600 bg-bunker-700 py-1.5 text-bunker-300 hover:border-primary-400/50",
|
||||||
newVersion?.secretValueHidden ? "pl-8 pr-2" : "px-2"
|
newVersion?.secretValueHidden ? "pl-8 pr-2" : "px-2"
|
||||||
@@ -287,7 +296,7 @@ export const SecretApprovalRequestChangeItem = ({
|
|||||||
<div className="mb-2">
|
<div className="mb-2">
|
||||||
<div className="text-sm font-medium text-mineshaft-300">Comment</div>
|
<div className="text-sm font-medium text-mineshaft-300">Comment</div>
|
||||||
<div className="thin-scrollbar max-h-[5rem] max-w-[34rem] overflow-y-auto break-words text-sm xl:max-w-[28rem]">
|
<div className="thin-scrollbar max-h-[5rem] max-w-[34rem] overflow-y-auto break-words text-sm xl:max-w-[28rem]">
|
||||||
{newVersion?.secretComment || (
|
{(newVersion?.secretComment ?? secretVersion?.secretComment) || (
|
||||||
<span className="text-sm text-mineshaft-300">-</span>
|
<span className="text-sm text-mineshaft-300">-</span>
|
||||||
)}{" "}
|
)}{" "}
|
||||||
</div>
|
</div>
|
||||||
@@ -315,9 +324,9 @@ export const SecretApprovalRequestChangeItem = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="mb-2">
|
<div className="mb-2">
|
||||||
<div className="text-sm font-medium text-mineshaft-300">Metadata</div>
|
<div className="text-sm font-medium text-mineshaft-300">Metadata</div>
|
||||||
{newVersion?.secretMetadata?.length ? (
|
{(newVersion?.secretMetadata ?? secretVersion?.secretMetadata)?.length ? (
|
||||||
<div className="mt-1 flex flex-wrap gap-2 text-sm text-mineshaft-300">
|
<div className="mt-1 flex flex-wrap gap-2 text-sm text-mineshaft-300">
|
||||||
{newVersion.secretMetadata?.map((el) => (
|
{(newVersion?.secretMetadata ?? secretVersion?.secretMetadata)?.map((el) => (
|
||||||
<div key={el.key} className="flex items-center">
|
<div key={el.key} className="flex items-center">
|
||||||
<Tag
|
<Tag
|
||||||
size="xs"
|
size="xs"
|
||||||
@@ -353,6 +362,15 @@ export const SecretApprovalRequestChangeItem = ({
|
|||||||
<p className="text-sm text-mineshaft-300">-</p>
|
<p className="text-sm text-mineshaft-300">-</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
<div className="mb-2">
|
||||||
|
<div className="text-sm font-medium text-mineshaft-300">Multi-line Encoding</div>
|
||||||
|
<div className="text-sm">
|
||||||
|
{newVersion?.skipMultilineEncoding?.toString() ??
|
||||||
|
secretVersion?.skipMultilineEncoding?.toString() ?? (
|
||||||
|
<span className="text-sm text-mineshaft-300">-</span>
|
||||||
|
)}{" "}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="text-md flex w-full items-center justify-center rounded-md border border-mineshaft-600 bg-mineshaft-800 text-mineshaft-300 xl:w-1/2">
|
<div className="text-md flex w-full items-center justify-center rounded-md border border-mineshaft-600 bg-mineshaft-800 text-mineshaft-300 xl:w-1/2">
|
||||||
|
|||||||
Reference in New Issue
Block a user