mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 09:26:47 +00:00
feat(infisical-pg): completed tag support to all secret operations
This commit is contained in:
Vendored
+26
-25
@@ -83,23 +83,23 @@ import {
|
|||||||
TSamlConfigs,
|
TSamlConfigs,
|
||||||
TSamlConfigsInsert,
|
TSamlConfigsInsert,
|
||||||
TSamlConfigsUpdate,
|
TSamlConfigsUpdate,
|
||||||
TSapApprovers,
|
|
||||||
TSapApproversInsert,
|
|
||||||
TSapApproversUpdate,
|
|
||||||
TSaRequestSecrets,
|
|
||||||
TSaRequestSecretsInsert,
|
|
||||||
TSaRequestSecretsUpdate,
|
|
||||||
TSaRequestSecretTags,
|
|
||||||
TSaRequestSecretTagsInsert,
|
|
||||||
TSaRequestSecretTagsUpdate,
|
|
||||||
TSarReviewers,
|
|
||||||
TSarReviewersInsert,
|
|
||||||
TSarReviewersUpdate,
|
|
||||||
TSecretApprovalPolicies,
|
TSecretApprovalPolicies,
|
||||||
|
TSecretApprovalPoliciesApprovers,
|
||||||
|
TSecretApprovalPoliciesApproversInsert,
|
||||||
|
TSecretApprovalPoliciesApproversUpdate,
|
||||||
TSecretApprovalPoliciesInsert,
|
TSecretApprovalPoliciesInsert,
|
||||||
TSecretApprovalPoliciesUpdate,
|
TSecretApprovalPoliciesUpdate,
|
||||||
TSecretApprovalRequests,
|
TSecretApprovalRequests,
|
||||||
|
TSecretApprovalRequestSecretTags,
|
||||||
|
TSecretApprovalRequestSecretTagsInsert,
|
||||||
|
TSecretApprovalRequestSecretTagsUpdate,
|
||||||
TSecretApprovalRequestsInsert,
|
TSecretApprovalRequestsInsert,
|
||||||
|
TSecretApprovalRequestsReviewers,
|
||||||
|
TSecretApprovalRequestsReviewersInsert,
|
||||||
|
TSecretApprovalRequestsReviewersUpdate,
|
||||||
|
TSecretApprovalRequestsSecrets,
|
||||||
|
TSecretApprovalRequestsSecretsInsert,
|
||||||
|
TSecretApprovalRequestsSecretsUpdate,
|
||||||
TSecretApprovalRequestsUpdate,
|
TSecretApprovalRequestsUpdate,
|
||||||
TSecretBlindIndexes,
|
TSecretBlindIndexes,
|
||||||
TSecretBlindIndexesInsert,
|
TSecretBlindIndexesInsert,
|
||||||
@@ -166,7 +166,8 @@ import {
|
|||||||
TUsersUpdate,
|
TUsersUpdate,
|
||||||
TWebhooks,
|
TWebhooks,
|
||||||
TWebhooksInsert,
|
TWebhooksInsert,
|
||||||
TWebhooksUpdate} from "@app/db/schemas";
|
TWebhooksUpdate
|
||||||
|
} from "@app/db/schemas";
|
||||||
|
|
||||||
declare module "knex/types/tables" {
|
declare module "knex/types/tables" {
|
||||||
interface Tables {
|
interface Tables {
|
||||||
@@ -327,9 +328,9 @@ declare module "knex/types/tables" {
|
|||||||
TSecretApprovalPoliciesUpdate
|
TSecretApprovalPoliciesUpdate
|
||||||
>;
|
>;
|
||||||
[TableName.SecretApprovalPolicyApprover]: Knex.CompositeTableType<
|
[TableName.SecretApprovalPolicyApprover]: Knex.CompositeTableType<
|
||||||
TSapApprovers,
|
TSecretApprovalPoliciesApprovers,
|
||||||
TSapApproversInsert,
|
TSecretApprovalPoliciesApproversInsert,
|
||||||
TSapApproversUpdate
|
TSecretApprovalPoliciesApproversUpdate
|
||||||
>;
|
>;
|
||||||
[TableName.SecretApprovalRequest]: Knex.CompositeTableType<
|
[TableName.SecretApprovalRequest]: Knex.CompositeTableType<
|
||||||
TSecretApprovalRequests,
|
TSecretApprovalRequests,
|
||||||
@@ -337,19 +338,19 @@ declare module "knex/types/tables" {
|
|||||||
TSecretApprovalRequestsUpdate
|
TSecretApprovalRequestsUpdate
|
||||||
>;
|
>;
|
||||||
[TableName.SecretApprovalRequestReviewer]: Knex.CompositeTableType<
|
[TableName.SecretApprovalRequestReviewer]: Knex.CompositeTableType<
|
||||||
TSarReviewers,
|
TSecretApprovalRequestsReviewers,
|
||||||
TSarReviewersInsert,
|
TSecretApprovalRequestsReviewersInsert,
|
||||||
TSarReviewersUpdate
|
TSecretApprovalRequestsReviewersUpdate
|
||||||
>;
|
>;
|
||||||
[TableName.SecretApprovalRequestSecret]: Knex.CompositeTableType<
|
[TableName.SecretApprovalRequestSecret]: Knex.CompositeTableType<
|
||||||
TSaRequestSecrets,
|
TSecretApprovalRequestsSecrets,
|
||||||
TSaRequestSecretsInsert,
|
TSecretApprovalRequestsSecretsInsert,
|
||||||
TSaRequestSecretsUpdate
|
TSecretApprovalRequestsSecretsUpdate
|
||||||
>;
|
>;
|
||||||
[TableName.SecretApprovalRequestSecretTag]: Knex.CompositeTableType<
|
[TableName.SecretApprovalRequestSecretTag]: Knex.CompositeTableType<
|
||||||
TSaRequestSecretTags,
|
TSecretApprovalRequestSecretTags,
|
||||||
TSaRequestSecretTagsInsert,
|
TSecretApprovalRequestSecretTagsInsert,
|
||||||
TSaRequestSecretTagsUpdate
|
TSecretApprovalRequestSecretTagsUpdate
|
||||||
>;
|
>;
|
||||||
[TableName.SecretRotation]: Knex.CompositeTableType<
|
[TableName.SecretRotation]: Knex.CompositeTableType<
|
||||||
TSecretRotations,
|
TSecretRotations,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
SecretApprovalRequestsSchema,
|
SecretApprovalRequestsSchema,
|
||||||
SecretApprovalRequestsSecretsSchema,
|
SecretApprovalRequestsSecretsSchema,
|
||||||
SecretsSchema,
|
SecretsSchema,
|
||||||
|
SecretTagsSchema,
|
||||||
SecretVersionsSchema
|
SecretVersionsSchema
|
||||||
} from "@app/db/schemas";
|
} from "@app/db/schemas";
|
||||||
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||||
@@ -90,77 +91,6 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
server.route({
|
|
||||||
url: "/:id",
|
|
||||||
method: "GET",
|
|
||||||
schema: {
|
|
||||||
params: z.object({
|
|
||||||
id: z.string()
|
|
||||||
}),
|
|
||||||
response: {
|
|
||||||
200: z.object({
|
|
||||||
approval: SecretApprovalRequestsSchema.merge(
|
|
||||||
z.object({
|
|
||||||
// secretPath: z.string(),
|
|
||||||
policy: z.object({
|
|
||||||
id: z.string(),
|
|
||||||
name: z.string(),
|
|
||||||
approvals: z.number(),
|
|
||||||
approvers: z.string().array(),
|
|
||||||
secretPath: z.string().optional().nullable()
|
|
||||||
}),
|
|
||||||
environment: z.string(),
|
|
||||||
reviewers: z.object({ member: z.string(), status: z.string() }).array(),
|
|
||||||
approvers: z.string().array(),
|
|
||||||
secretPath: z.string(),
|
|
||||||
commits: SecretApprovalRequestsSecretsSchema.omit({ secretBlindIndex: true })
|
|
||||||
.merge(
|
|
||||||
z.object({
|
|
||||||
secret: SecretsSchema.pick({
|
|
||||||
id: true,
|
|
||||||
secretKeyIV: true,
|
|
||||||
secretKeyTag: true,
|
|
||||||
secretKeyCiphertext: true,
|
|
||||||
secretValueIV: true,
|
|
||||||
secretValueTag: true,
|
|
||||||
secretValueCiphertext: true,
|
|
||||||
secretCommentIV: true,
|
|
||||||
secretCommentTag: true,
|
|
||||||
secretCommentCiphertext: true
|
|
||||||
})
|
|
||||||
.optional()
|
|
||||||
.nullable(),
|
|
||||||
secretVersion: SecretVersionsSchema.pick({
|
|
||||||
id: true,
|
|
||||||
secretKeyIV: true,
|
|
||||||
secretKeyTag: true,
|
|
||||||
secretKeyCiphertext: true,
|
|
||||||
secretValueIV: true,
|
|
||||||
secretValueTag: true,
|
|
||||||
secretValueCiphertext: true,
|
|
||||||
secretCommentIV: true,
|
|
||||||
secretCommentTag: true,
|
|
||||||
secretCommentCiphertext: true
|
|
||||||
}).optional()
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.array()
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onRequest: verifyAuth([AuthMode.JWT]),
|
|
||||||
handler: async (req) => {
|
|
||||||
const approval = await server.services.secretApprovalRequest.getSecretApprovalDetails({
|
|
||||||
actor: req.permission.type,
|
|
||||||
actorId: req.permission.id,
|
|
||||||
id: req.params.id
|
|
||||||
});
|
|
||||||
return { approval };
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
server.route({
|
server.route({
|
||||||
url: "/:id/merge",
|
url: "/:id/merge",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -257,4 +187,92 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
|||||||
return { approval };
|
return { approval };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const tagSchema = SecretTagsSchema.pick({
|
||||||
|
id: true,
|
||||||
|
slug: true,
|
||||||
|
name: true,
|
||||||
|
color: true
|
||||||
|
})
|
||||||
|
.array()
|
||||||
|
.optional();
|
||||||
|
server.route({
|
||||||
|
url: "/:id",
|
||||||
|
method: "GET",
|
||||||
|
schema: {
|
||||||
|
params: z.object({
|
||||||
|
id: z.string()
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
approval: SecretApprovalRequestsSchema.merge(
|
||||||
|
z.object({
|
||||||
|
// secretPath: z.string(),
|
||||||
|
policy: z.object({
|
||||||
|
id: z.string(),
|
||||||
|
name: z.string(),
|
||||||
|
approvals: z.number(),
|
||||||
|
approvers: z.string().array(),
|
||||||
|
secretPath: z.string().optional().nullable()
|
||||||
|
}),
|
||||||
|
environment: z.string(),
|
||||||
|
reviewers: z.object({ member: z.string(), status: z.string() }).array(),
|
||||||
|
approvers: z.string().array(),
|
||||||
|
secretPath: z.string(),
|
||||||
|
commits: SecretApprovalRequestsSecretsSchema.omit({ secretBlindIndex: true })
|
||||||
|
.merge(
|
||||||
|
z.object({
|
||||||
|
tags: tagSchema,
|
||||||
|
secret: SecretsSchema.pick({
|
||||||
|
id: true,
|
||||||
|
version: true,
|
||||||
|
secretKeyIV: true,
|
||||||
|
secretKeyTag: true,
|
||||||
|
secretKeyCiphertext: true,
|
||||||
|
secretValueIV: true,
|
||||||
|
secretValueTag: true,
|
||||||
|
secretValueCiphertext: true,
|
||||||
|
secretCommentIV: true,
|
||||||
|
secretCommentTag: true,
|
||||||
|
secretCommentCiphertext: true
|
||||||
|
})
|
||||||
|
.optional()
|
||||||
|
.nullable(),
|
||||||
|
secretVersion: SecretVersionsSchema.pick({
|
||||||
|
id: true,
|
||||||
|
version: true,
|
||||||
|
secretKeyIV: true,
|
||||||
|
secretKeyTag: true,
|
||||||
|
secretKeyCiphertext: true,
|
||||||
|
secretValueIV: true,
|
||||||
|
secretValueTag: true,
|
||||||
|
secretValueCiphertext: true,
|
||||||
|
secretCommentIV: true,
|
||||||
|
secretCommentTag: true,
|
||||||
|
secretCommentCiphertext: true
|
||||||
|
})
|
||||||
|
.merge(
|
||||||
|
z.object({
|
||||||
|
tags: tagSchema
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.optional()
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.array()
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const approval = await server.services.secretApprovalRequest.getSecretApprovalDetails({
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorId: req.permission.id,
|
||||||
|
id: req.params.id
|
||||||
|
});
|
||||||
|
return { approval };
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
+154
-64
@@ -1,19 +1,35 @@
|
|||||||
import { Knex } from "knex";
|
import { Knex } from "knex";
|
||||||
|
|
||||||
import { TDbClient } from "@app/db";
|
import { TDbClient } from "@app/db";
|
||||||
import { TableName } from "@app/db/schemas";
|
import { SecretApprovalRequestsSecretsSchema, TableName } from "@app/db/schemas";
|
||||||
import { DatabaseError } from "@app/lib/errors";
|
import { DatabaseError } from "@app/lib/errors";
|
||||||
import { ormify, selectAllTableCols } from "@app/lib/knex";
|
import { ormify, selectAllTableCols, sqlNestRelationships } from "@app/lib/knex";
|
||||||
|
|
||||||
export type TSecretApprovalRequestSecretDALFactory = ReturnType<typeof secretApprovalRequestSecretDALFactory>;
|
export type TSecretApprovalRequestSecretDALFactory = ReturnType<
|
||||||
|
typeof secretApprovalRequestSecretDALFactory
|
||||||
|
>;
|
||||||
|
|
||||||
export const secretApprovalRequestSecretDALFactory = (db: TDbClient) => {
|
export const secretApprovalRequestSecretDALFactory = (db: TDbClient) => {
|
||||||
const sarSecretOrm = ormify(db, TableName.SecretApprovalRequestSecret);
|
const secretApprovalRequestSecretOrm = ormify(db, TableName.SecretApprovalRequestSecret);
|
||||||
|
const secretApprovalRequestSecretTagOrm = ormify(db, TableName.SecretApprovalRequestSecretTag);
|
||||||
|
|
||||||
const findByRequestId = async (requestId: string, tx?: Knex) => {
|
const findByRequestId = async (requestId: string, tx?: Knex) => {
|
||||||
try {
|
try {
|
||||||
const doc = await (tx || db)(TableName.SecretApprovalRequestSecret)
|
const doc = await (tx || db)({
|
||||||
|
secVerTag: TableName.SecretTag
|
||||||
|
})
|
||||||
|
.from(TableName.SecretApprovalRequestSecret)
|
||||||
.where({ requestId })
|
.where({ requestId })
|
||||||
|
.leftJoin(
|
||||||
|
TableName.SecretApprovalRequestSecretTag,
|
||||||
|
`${TableName.SecretApprovalRequestSecret}.id`,
|
||||||
|
`${TableName.SecretApprovalRequestSecretTag}.secretId`
|
||||||
|
)
|
||||||
|
.leftJoin(
|
||||||
|
TableName.SecretTag,
|
||||||
|
`${TableName.SecretApprovalRequestSecretTag}.tagId`,
|
||||||
|
`${TableName.SecretTag}.id`
|
||||||
|
)
|
||||||
.leftJoin(
|
.leftJoin(
|
||||||
TableName.Secret,
|
TableName.Secret,
|
||||||
`${TableName.SecretApprovalRequestSecret}.secretId`,
|
`${TableName.SecretApprovalRequestSecret}.secretId`,
|
||||||
@@ -24,7 +40,30 @@ export const secretApprovalRequestSecretDALFactory = (db: TDbClient) => {
|
|||||||
`${TableName.SecretVersion}.id`,
|
`${TableName.SecretVersion}.id`,
|
||||||
`${TableName.SecretApprovalRequestSecret}.secretVersion`
|
`${TableName.SecretApprovalRequestSecret}.secretVersion`
|
||||||
)
|
)
|
||||||
|
.leftJoin(
|
||||||
|
TableName.SecretVersionTag,
|
||||||
|
`${TableName.SecretVersionTag}.${TableName.SecretVersion}Id`,
|
||||||
|
`${TableName.SecretVersion}.id`
|
||||||
|
)
|
||||||
|
.leftJoin(
|
||||||
|
db.ref(TableName.SecretTag).as("secVerTag"),
|
||||||
|
`${TableName.SecretVersionTag}.${TableName.SecretTag}Id`,
|
||||||
|
db.ref("id").withSchema("secVerTag")
|
||||||
|
)
|
||||||
.select(selectAllTableCols(TableName.SecretApprovalRequestSecret))
|
.select(selectAllTableCols(TableName.SecretApprovalRequestSecret))
|
||||||
|
.select({
|
||||||
|
secVerTagId: "secVerTag.id",
|
||||||
|
secVerTagColor: "secVerTag.color",
|
||||||
|
secVerTagSlug: "secVerTag.slug",
|
||||||
|
secVerTagName: "secVerTag.name"
|
||||||
|
})
|
||||||
|
.select(
|
||||||
|
db.ref("id").withSchema(TableName.SecretTag).as("tagId"),
|
||||||
|
db.ref("id").withSchema(TableName.SecretApprovalRequestSecretTag).as("tagJnId"),
|
||||||
|
db.ref("color").withSchema(TableName.SecretTag).as("tagColor"),
|
||||||
|
db.ref("slug").withSchema(TableName.SecretTag).as("tagSlug"),
|
||||||
|
db.ref("name").withSchema(TableName.SecretTag).as("tagName")
|
||||||
|
)
|
||||||
.select(
|
.select(
|
||||||
db.ref("secretBlindIndex").withSchema(TableName.Secret).as("orgSecBlindIndex"),
|
db.ref("secretBlindIndex").withSchema(TableName.Secret).as("orgSecBlindIndex"),
|
||||||
db.ref("version").withSchema(TableName.Secret).as("orgSecVersion"),
|
db.ref("version").withSchema(TableName.Secret).as("orgSecVersion"),
|
||||||
@@ -42,7 +81,6 @@ export const secretApprovalRequestSecretDALFactory = (db: TDbClient) => {
|
|||||||
.as("orgSecCommentCiphertext")
|
.as("orgSecCommentCiphertext")
|
||||||
)
|
)
|
||||||
.select(
|
.select(
|
||||||
// db.ref("secretBlindIndex").withSchema(TableName.Secret).as("orgSecBlindInex"),
|
|
||||||
db.ref("version").withSchema(TableName.SecretVersion).as("secVerVersion"),
|
db.ref("version").withSchema(TableName.SecretVersion).as("secVerVersion"),
|
||||||
db.ref("secretKeyIV").withSchema(TableName.SecretVersion).as("secVerKeyIV"),
|
db.ref("secretKeyIV").withSchema(TableName.SecretVersion).as("secVerKeyIV"),
|
||||||
db.ref("secretKeyTag").withSchema(TableName.SecretVersion).as("secVerKeyTag"),
|
db.ref("secretKeyTag").withSchema(TableName.SecretVersion).as("secVerKeyTag"),
|
||||||
@@ -63,67 +101,119 @@ export const secretApprovalRequestSecretDALFactory = (db: TDbClient) => {
|
|||||||
.withSchema(TableName.SecretVersion)
|
.withSchema(TableName.SecretVersion)
|
||||||
.as("secVerCommentCiphertext")
|
.as("secVerCommentCiphertext")
|
||||||
);
|
);
|
||||||
return doc.map(
|
const formatedDoc = sqlNestRelationships({
|
||||||
({
|
data: doc,
|
||||||
orgSecKeyIV,
|
key: "id",
|
||||||
orgSecKeyTag,
|
parentMapper: (data) =>
|
||||||
orgSecValueIV,
|
SecretApprovalRequestsSecretsSchema.omit({ secretVersion: true }).parse(data),
|
||||||
orgSecVersion,
|
childrenMapper: [
|
||||||
orgSecValueTag,
|
{
|
||||||
orgSecCommentIV,
|
key: "tagJnId",
|
||||||
orgSecBlindIndex,
|
label: "tags" as const,
|
||||||
orgSecCommentTag,
|
mapper: ({ tagId: id, tagName: name, tagSlug: slug, tagColor: color }) => ({
|
||||||
orgSecKeyCiphertext,
|
id,
|
||||||
orgSecValueCiphertext,
|
name,
|
||||||
orgSecCommentCiphertext,
|
slug,
|
||||||
secVerCommentIV,
|
color
|
||||||
secVerCommentCiphertext,
|
})
|
||||||
secVerCommentTag,
|
},
|
||||||
secVerValueCiphertext,
|
{
|
||||||
secVerKeyIV,
|
key: "secretId",
|
||||||
secVerKeyTag,
|
label: "secret" as const,
|
||||||
secVerValueIV,
|
mapper: ({
|
||||||
secVerVersion,
|
orgSecKeyIV,
|
||||||
secVerValueTag,
|
orgSecKeyTag,
|
||||||
secVerKeyCiphertext,
|
orgSecValueIV,
|
||||||
...el
|
orgSecVersion,
|
||||||
}) => ({
|
orgSecValueTag,
|
||||||
...el,
|
orgSecCommentIV,
|
||||||
secret: el.secretId
|
orgSecBlindIndex,
|
||||||
? {
|
orgSecCommentTag,
|
||||||
id: el.secretId,
|
orgSecKeyCiphertext,
|
||||||
version: orgSecVersion,
|
orgSecValueCiphertext,
|
||||||
secretBlindIndex: orgSecBlindIndex,
|
orgSecCommentCiphertext,
|
||||||
secretKeyIV: orgSecKeyIV,
|
secretId
|
||||||
secretKeyTag: orgSecKeyTag,
|
}) =>
|
||||||
secretKeyCiphertext: orgSecKeyCiphertext,
|
secretId
|
||||||
secretValueIV: orgSecValueIV,
|
? {
|
||||||
secretValueTag: orgSecValueTag,
|
id: secretId,
|
||||||
secretValueCiphertext: orgSecValueCiphertext,
|
version: orgSecVersion,
|
||||||
secretCommentIV: orgSecCommentIV,
|
secretBlindIndex: orgSecBlindIndex,
|
||||||
secretCommentTag: orgSecCommentTag,
|
secretKeyIV: orgSecKeyIV,
|
||||||
secretCommentCiphertext: orgSecCommentCiphertext
|
secretKeyTag: orgSecKeyTag,
|
||||||
|
secretKeyCiphertext: orgSecKeyCiphertext,
|
||||||
|
secretValueIV: orgSecValueIV,
|
||||||
|
secretValueTag: orgSecValueTag,
|
||||||
|
secretValueCiphertext: orgSecValueCiphertext,
|
||||||
|
secretCommentIV: orgSecCommentIV,
|
||||||
|
secretCommentTag: orgSecCommentTag,
|
||||||
|
secretCommentCiphertext: orgSecCommentCiphertext
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "secretVersion",
|
||||||
|
label: "secretVersion" as const,
|
||||||
|
mapper: ({
|
||||||
|
secVerCommentIV,
|
||||||
|
secVerCommentCiphertext,
|
||||||
|
secVerCommentTag,
|
||||||
|
secVerValueCiphertext,
|
||||||
|
secVerKeyIV,
|
||||||
|
secVerKeyTag,
|
||||||
|
secVerValueIV,
|
||||||
|
secretVersion,
|
||||||
|
secVerValueTag,
|
||||||
|
secVerKeyCiphertext,
|
||||||
|
secVerVersion
|
||||||
|
}) =>
|
||||||
|
secretVersion
|
||||||
|
? {
|
||||||
|
version: secVerVersion,
|
||||||
|
id: secretVersion,
|
||||||
|
secretKeyIV: secVerKeyIV,
|
||||||
|
secretKeyTag: secVerKeyTag,
|
||||||
|
secretKeyCiphertext: secVerKeyCiphertext,
|
||||||
|
secretValueIV: secVerValueIV,
|
||||||
|
secretValueTag: secVerValueTag,
|
||||||
|
secretValueCiphertext: secVerValueCiphertext,
|
||||||
|
secretCommentIV: secVerCommentIV,
|
||||||
|
secretCommentTag: secVerCommentTag,
|
||||||
|
secretCommentCiphertext: secVerCommentCiphertext
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
childrenMapper: [
|
||||||
|
{
|
||||||
|
key: "secVerTagId",
|
||||||
|
label: "tags" as const,
|
||||||
|
mapper: ({
|
||||||
|
secVerTagId: id,
|
||||||
|
secVerTagName: name,
|
||||||
|
secVerTagSlug: slug,
|
||||||
|
secVerTagColor: color
|
||||||
|
}) => ({
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
slug,
|
||||||
|
color
|
||||||
|
})
|
||||||
}
|
}
|
||||||
: undefined,
|
]
|
||||||
secretVersion: el.secretVersion
|
}
|
||||||
? {
|
]
|
||||||
id: el.secretVersion,
|
});
|
||||||
secretKeyIV: secVerKeyIV,
|
return formatedDoc?.map(({ secret, secretVersion, ...el }) => ({
|
||||||
secretKeyTag: secVerKeyTag,
|
...el,
|
||||||
secretKeyCiphertext: secVerKeyCiphertext,
|
secret: secret?.[0],
|
||||||
secretValueIV: secVerValueIV,
|
secretVersion: secretVersion?.[0]
|
||||||
secretValueTag: secVerValueTag,
|
}));
|
||||||
secretValueCiphertext: secVerValueCiphertext,
|
|
||||||
secretCommentIV: secVerCommentIV,
|
|
||||||
secretCommentTag: secVerCommentTag,
|
|
||||||
secretCommentCiphertext: secVerCommentCiphertext
|
|
||||||
}
|
|
||||||
: undefined
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new DatabaseError({ error, name: "FindByRequestId" });
|
throw new DatabaseError({ error, name: "FindByRequestId" });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return { ...sarSecretOrm, findByRequestId };
|
return {
|
||||||
|
...secretApprovalRequestSecretOrm,
|
||||||
|
findByRequestId,
|
||||||
|
insertApprovalSecretTags: secretApprovalRequestSecretTagOrm.insertMany
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
+71
-36
@@ -8,7 +8,7 @@ import {
|
|||||||
TSecretApprovalRequestsSecretsInsert
|
TSecretApprovalRequestsSecretsInsert
|
||||||
} from "@app/db/schemas";
|
} from "@app/db/schemas";
|
||||||
import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
|
import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
|
||||||
import { groupBy, pick } from "@app/lib/fn";
|
import { groupBy, pick, unique } from "@app/lib/fn";
|
||||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||||
import { ActorType } from "@app/services/auth/auth-type";
|
import { ActorType } from "@app/services/auth/auth-type";
|
||||||
import { TSecretBlindIndexDALFactory } from "@app/services/secret/secret-blind-index-dal";
|
import { TSecretBlindIndexDALFactory } from "@app/services/secret/secret-blind-index-dal";
|
||||||
@@ -16,6 +16,7 @@ import { TSecretQueueFactory } from "@app/services/secret/secret-queue";
|
|||||||
import { TSecretServiceFactory } from "@app/services/secret/secret-service";
|
import { TSecretServiceFactory } from "@app/services/secret/secret-service";
|
||||||
import { TSecretVersionDALFactory } from "@app/services/secret/secret-version-dal";
|
import { TSecretVersionDALFactory } from "@app/services/secret/secret-version-dal";
|
||||||
import { TSecretFolderDALFactory } from "@app/services/secret-folder/secret-folder-dal";
|
import { TSecretFolderDALFactory } from "@app/services/secret-folder/secret-folder-dal";
|
||||||
|
import { TSecretTagDALFactory } from "@app/services/secret-tag/secret-tag-dal";
|
||||||
|
|
||||||
import { TPermissionServiceFactory } from "../permission/permission-service";
|
import { TPermissionServiceFactory } from "../permission/permission-service";
|
||||||
import { ProjectPermissionActions, ProjectPermissionSub } from "../permission/project-permission";
|
import { ProjectPermissionActions, ProjectPermissionSub } from "../permission/project-permission";
|
||||||
@@ -39,12 +40,13 @@ import {
|
|||||||
type TSecretApprovalRequestServiceFactoryDep = {
|
type TSecretApprovalRequestServiceFactoryDep = {
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||||
secretApprovalRequestDAL: TSecretApprovalRequestDALFactory;
|
secretApprovalRequestDAL: TSecretApprovalRequestDALFactory;
|
||||||
sarSecretDAL: TSecretApprovalRequestSecretDALFactory;
|
secretApprovalRequestSecretDAL: TSecretApprovalRequestSecretDALFactory;
|
||||||
sarReviewerDAL: TSecretApprovalRequestReviewerDALFactory;
|
secretApprovalRequestReviewerDAL: TSecretApprovalRequestReviewerDALFactory;
|
||||||
folderDAL: Pick<
|
folderDAL: Pick<
|
||||||
TSecretFolderDALFactory,
|
TSecretFolderDALFactory,
|
||||||
"findBySecretPath" | "findById" | "findSecretPathByFolderIds"
|
"findBySecretPath" | "findById" | "findSecretPathByFolderIds"
|
||||||
>;
|
>;
|
||||||
|
secretTagDAL: Pick<TSecretTagDALFactory, "findManyTagsById">;
|
||||||
secretBlindIndexDAL: Pick<TSecretBlindIndexDALFactory, "findOne">;
|
secretBlindIndexDAL: Pick<TSecretBlindIndexDALFactory, "findOne">;
|
||||||
snapshotService: Pick<TSecretSnapshotServiceFactory, "performSnapshot">;
|
snapshotService: Pick<TSecretSnapshotServiceFactory, "performSnapshot">;
|
||||||
secretVersionDAL: Pick<TSecretVersionDALFactory, "findLatestVersionMany">;
|
secretVersionDAL: Pick<TSecretVersionDALFactory, "findLatestVersionMany">;
|
||||||
@@ -66,8 +68,9 @@ export type TSecretApprovalRequestServiceFactory = ReturnType<
|
|||||||
export const secretApprovalRequestServiceFactory = ({
|
export const secretApprovalRequestServiceFactory = ({
|
||||||
secretApprovalRequestDAL,
|
secretApprovalRequestDAL,
|
||||||
folderDAL,
|
folderDAL,
|
||||||
sarReviewerDAL,
|
secretTagDAL,
|
||||||
sarSecretDAL,
|
secretApprovalRequestReviewerDAL,
|
||||||
|
secretApprovalRequestSecretDAL,
|
||||||
secretBlindIndexDAL,
|
secretBlindIndexDAL,
|
||||||
permissionService,
|
permissionService,
|
||||||
snapshotService,
|
snapshotService,
|
||||||
@@ -137,7 +140,7 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
throw new UnauthorizedError({ message: "User has no access" });
|
throw new UnauthorizedError({ message: "User has no access" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const secrets = await sarSecretDAL.findByRequestId(secretApprovalRequest.id);
|
const secrets = await secretApprovalRequestSecretDAL.findByRequestId(secretApprovalRequest.id);
|
||||||
const secretPath = await folderDAL.findSecretPathByFolderIds(secretApprovalRequest.projectId, [
|
const secretPath = await folderDAL.findSecretPathByFolderIds(secretApprovalRequest.projectId, [
|
||||||
secretApprovalRequest.folderId
|
secretApprovalRequest.folderId
|
||||||
]);
|
]);
|
||||||
@@ -163,8 +166,8 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
) {
|
) {
|
||||||
throw new UnauthorizedError({ message: "User has no access" });
|
throw new UnauthorizedError({ message: "User has no access" });
|
||||||
}
|
}
|
||||||
const reviewStatus = await sarReviewerDAL.transaction(async (tx) => {
|
const reviewStatus = await secretApprovalRequestReviewerDAL.transaction(async (tx) => {
|
||||||
const review = await sarReviewerDAL.findOne(
|
const review = await secretApprovalRequestReviewerDAL.findOne(
|
||||||
{
|
{
|
||||||
requestId: secretApprovalRequest.id,
|
requestId: secretApprovalRequest.id,
|
||||||
member: membership.id
|
member: membership.id
|
||||||
@@ -172,7 +175,7 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
if (!review) {
|
if (!review) {
|
||||||
return sarReviewerDAL.create(
|
return secretApprovalRequestReviewerDAL.create(
|
||||||
{
|
{
|
||||||
status,
|
status,
|
||||||
requestId: secretApprovalRequest.id,
|
requestId: secretApprovalRequest.id,
|
||||||
@@ -181,7 +184,7 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return sarReviewerDAL.updateById(review.id, { status }, tx);
|
return secretApprovalRequestReviewerDAL.updateById(review.id, { status }, tx);
|
||||||
});
|
});
|
||||||
return reviewStatus;
|
return reviewStatus;
|
||||||
};
|
};
|
||||||
@@ -255,7 +258,9 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
|
|
||||||
if (!hasMinApproval)
|
if (!hasMinApproval)
|
||||||
throw new BadRequestError({ message: "Doesn't have minimum approvals needed" });
|
throw new BadRequestError({ message: "Doesn't have minimum approvals needed" });
|
||||||
const secretApprovalSecrets = await sarSecretDAL.findByRequestId(secretApprovalRequest.id);
|
const secretApprovalSecrets = await secretApprovalRequestSecretDAL.findByRequestId(
|
||||||
|
secretApprovalRequest.id
|
||||||
|
);
|
||||||
if (!secretApprovalSecrets) throw new BadRequestError({ message: "No secrets found" });
|
if (!secretApprovalSecrets) throw new BadRequestError({ message: "No secrets found" });
|
||||||
|
|
||||||
const conflicts: Array<{ secretId: string; op: CommitType }> = [];
|
const conflicts: Array<{ secretId: string; op: CommitType }> = [];
|
||||||
@@ -328,11 +333,12 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
"skipMultilineEncoding",
|
"skipMultilineEncoding",
|
||||||
"secretReminderNote",
|
"secretReminderNote",
|
||||||
"secretReminderRepeatDays",
|
"secretReminderRepeatDays",
|
||||||
"version",
|
|
||||||
"algorithm",
|
"algorithm",
|
||||||
"keyEncoding",
|
"keyEncoding",
|
||||||
"secretBlindIndex"
|
"secretBlindIndex"
|
||||||
]),
|
]),
|
||||||
|
tags: el?.tags.map(({ id }) => id),
|
||||||
|
version: 1,
|
||||||
type: SecretType.Shared
|
type: SecretType.Shared
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
@@ -344,25 +350,28 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
tx,
|
tx,
|
||||||
inputSecrets: secretUpdationCommits.map((el) => ({
|
inputSecrets: secretUpdationCommits.map((el) => ({
|
||||||
filter: {
|
filter: {
|
||||||
id: el.secretId,
|
id: el.secretId as string, // this null check is already checked at top on conflict strategy
|
||||||
type: SecretType.Shared
|
type: SecretType.Shared
|
||||||
},
|
},
|
||||||
data: pick(el, [
|
data: {
|
||||||
"secretCommentCiphertext",
|
tags: el?.tags.map(({ id }) => id),
|
||||||
"secretCommentTag",
|
...pick(el, [
|
||||||
"secretCommentIV",
|
"secretCommentCiphertext",
|
||||||
"secretValueIV",
|
"secretCommentTag",
|
||||||
"secretValueTag",
|
"secretCommentIV",
|
||||||
"secretValueCiphertext",
|
"secretValueIV",
|
||||||
"secretKeyCiphertext",
|
"secretValueTag",
|
||||||
"secretKeyTag",
|
"secretValueCiphertext",
|
||||||
"secretKeyIV",
|
"secretKeyCiphertext",
|
||||||
"metadata",
|
"secretKeyTag",
|
||||||
"skipMultilineEncoding",
|
"secretKeyIV",
|
||||||
"secretReminderNote",
|
"metadata",
|
||||||
"secretReminderRepeatDays",
|
"skipMultilineEncoding",
|
||||||
"secretBlindIndex"
|
"secretReminderNote",
|
||||||
])
|
"secretReminderRepeatDays",
|
||||||
|
"secretBlindIndex"
|
||||||
|
])
|
||||||
|
}
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
: [];
|
: [];
|
||||||
@@ -438,6 +447,7 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Blind index not found", name: "Update secret" });
|
throw new BadRequestError({ message: "Blind index not found", name: "Update secret" });
|
||||||
|
|
||||||
const commits: Omit<TSecretApprovalRequestsSecretsInsert, "requestId">[] = [];
|
const commits: Omit<TSecretApprovalRequestsSecretsInsert, "requestId">[] = [];
|
||||||
|
const commitTagIds: Record<string, string[]> = {};
|
||||||
// for created secret approval change
|
// for created secret approval change
|
||||||
const createdSecrets = data[CommitType.Create];
|
const createdSecrets = data[CommitType.Create];
|
||||||
if (createdSecrets && createdSecrets?.length) {
|
if (createdSecrets && createdSecrets?.length) {
|
||||||
@@ -452,12 +462,15 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
...createdSecrets.map(({ secretName, ...el }) => ({
|
...createdSecrets.map(({ secretName, ...el }) => ({
|
||||||
...el,
|
...el,
|
||||||
op: CommitType.Create as const,
|
op: CommitType.Create as const,
|
||||||
version: 0,
|
version: 1,
|
||||||
secretBlindIndex: keyName2BlindIndex[secretName],
|
secretBlindIndex: keyName2BlindIndex[secretName],
|
||||||
algorithm: SecretEncryptionAlgo.AES_256_GCM,
|
algorithm: SecretEncryptionAlgo.AES_256_GCM,
|
||||||
keyEncoding: SecretKeyEncoding.BASE64
|
keyEncoding: SecretKeyEncoding.BASE64
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
createdSecrets.forEach(({ tagIds, secretName }) => {
|
||||||
|
if (tagIds?.length) commitTagIds[keyName2BlindIndex[secretName]] = tagIds;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// not secret approval for update operations
|
// not secret approval for update operations
|
||||||
const updatedSecrets = data[CommitType.Update];
|
const updatedSecrets = data[CommitType.Update];
|
||||||
@@ -495,18 +508,21 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
updatedSecretIds
|
updatedSecretIds
|
||||||
);
|
);
|
||||||
commits.push(
|
commits.push(
|
||||||
...updatedSecrets.map(({ newSecretName, secretName, ...el }) => {
|
...updatedSecrets.map(({ newSecretName, secretName, tagIds, ...el }) => {
|
||||||
const secretId = secsGroupedByBlindIndex[keyName2BlindIndex[secretName]][0].id;
|
const secretId = secsGroupedByBlindIndex[keyName2BlindIndex[secretName]][0].id;
|
||||||
|
const secretBlindIndex =
|
||||||
|
newSecretName && newKeyName2BlindIndex[newSecretName]
|
||||||
|
? newKeyName2BlindIndex?.[secretName]
|
||||||
|
: keyName2BlindIndex[secretName];
|
||||||
|
// add tags
|
||||||
|
if (tagIds?.length) commitTagIds[keyName2BlindIndex[secretName]] = tagIds;
|
||||||
return {
|
return {
|
||||||
...latestSecretVersions[secretId],
|
...latestSecretVersions[secretId],
|
||||||
...el,
|
...el,
|
||||||
op: CommitType.Update as const,
|
op: CommitType.Update as const,
|
||||||
secret: secretId,
|
secret: secretId,
|
||||||
secretVersion: latestSecretVersions[secretId].id,
|
secretVersion: latestSecretVersions[secretId].id,
|
||||||
secretBlindIndex:
|
secretBlindIndex,
|
||||||
newSecretName && newKeyName2BlindIndex[newSecretName]
|
|
||||||
? newKeyName2BlindIndex?.[secretName]
|
|
||||||
: keyName2BlindIndex[secretName],
|
|
||||||
version: secsGroupedByBlindIndex[keyName2BlindIndex[secretName]][0].version || 1
|
version: secsGroupedByBlindIndex[keyName2BlindIndex[secretName]][0].version || 1
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
@@ -546,6 +562,11 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!commits.length) throw new BadRequestError({ message: "Empty commits" });
|
if (!commits.length) throw new BadRequestError({ message: "Empty commits" });
|
||||||
|
|
||||||
|
const tagIds = unique(Object.values(commitTagIds).flat());
|
||||||
|
const tags = tagIds.length ? await secretTagDAL.findManyTagsById(projectId, tagIds) : [];
|
||||||
|
if (tagIds.length !== tags.length) throw new BadRequestError({ message: "Tag not found" });
|
||||||
|
|
||||||
const secretApprovalRequest = await secretApprovalRequestDAL.transaction(async (tx) => {
|
const secretApprovalRequest = await secretApprovalRequestDAL.transaction(async (tx) => {
|
||||||
const doc = await secretApprovalRequestDAL.create(
|
const doc = await secretApprovalRequestDAL.create(
|
||||||
{
|
{
|
||||||
@@ -558,7 +579,7 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
},
|
},
|
||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
const approvalCommits = await sarSecretDAL.insertMany(
|
const approvalCommits = await secretApprovalRequestSecretDAL.insertMany(
|
||||||
commits.map(
|
commits.map(
|
||||||
({
|
({
|
||||||
version,
|
version,
|
||||||
@@ -607,6 +628,20 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
),
|
),
|
||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
|
const commitsGroupByBlindIndex = groupBy(approvalCommits, (i) => i.secretBlindIndex);
|
||||||
|
if (tagIds.length) {
|
||||||
|
await secretApprovalRequestSecretDAL.insertApprovalSecretTags(
|
||||||
|
Object.keys(commitTagIds).flatMap((blindIndex) =>
|
||||||
|
commitTagIds[blindIndex]
|
||||||
|
? commitTagIds[blindIndex].map((tagId) => ({
|
||||||
|
secretId: commitsGroupByBlindIndex[blindIndex][0].id,
|
||||||
|
tagId
|
||||||
|
}))
|
||||||
|
: []
|
||||||
|
),
|
||||||
|
tx
|
||||||
|
);
|
||||||
|
}
|
||||||
return { ...doc, commits: approvalCommits };
|
return { ...doc, commits: approvalCommits };
|
||||||
});
|
});
|
||||||
return secretApprovalRequest;
|
return secretApprovalRequest;
|
||||||
|
|||||||
@@ -16,3 +16,25 @@ export const groupBy = <T, Key extends string | number | symbol>(
|
|||||||
},
|
},
|
||||||
{} as Record<Key, T[]>
|
{} as Record<Key, T[]>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a list of items returns a new list with only
|
||||||
|
* unique items. Accepts an optional identity function
|
||||||
|
* to convert each item in the list to a comparable identity
|
||||||
|
* value
|
||||||
|
*/
|
||||||
|
export const unique = <T, K extends string | number | symbol>(
|
||||||
|
array: readonly T[],
|
||||||
|
toKey?: (item: T) => K
|
||||||
|
): T[] => {
|
||||||
|
const valueMap = array.reduce(
|
||||||
|
(acc, item) => {
|
||||||
|
const key = toKey ? toKey(item) : (item as any as string | number | symbol);
|
||||||
|
if (acc[key]) return acc;
|
||||||
|
acc[key] = item;
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{} as Record<string | number | symbol, T>
|
||||||
|
);
|
||||||
|
return Object.values(valueMap);
|
||||||
|
};
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ const sqlChildMapper = <
|
|||||||
childrenMapper: C
|
childrenMapper: C
|
||||||
) => {
|
) => {
|
||||||
if (!docsByPk) return;
|
if (!docsByPk) return;
|
||||||
|
|
||||||
type Cm = MappedRecord<(typeof childrenMapper)[number]>;
|
type Cm = MappedRecord<(typeof childrenMapper)[number]>;
|
||||||
childrenMapper.forEach(({ label, mapper, key: childPk, childrenMapper: nestedMappers }) => {
|
childrenMapper.forEach(({ label, mapper, key: childPk, childrenMapper: nestedMappers }) => {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
@@ -79,12 +80,12 @@ const sqlChildMapper = <
|
|||||||
|
|
||||||
if (doc?.[childPk] !== null && typeof doc?.[childPk] !== "undefined") {
|
if (doc?.[childPk] !== null && typeof doc?.[childPk] !== "undefined") {
|
||||||
const ck = `${prefix}-${label}-${doc[childPk]}`;
|
const ck = `${prefix}-${label}-${doc[childPk]}`;
|
||||||
|
const val = mapper(doc);
|
||||||
if (!lookupTable.has(ck)) {
|
if (!lookupTable.has(ck)) {
|
||||||
const val = mapper(doc);
|
|
||||||
if (typeof val !== "undefined" && val !== null) docsByPk[pk as keyof P][label].push(val);
|
if (typeof val !== "undefined" && val !== null) docsByPk[pk as keyof P][label].push(val);
|
||||||
lookupTable.add(ck);
|
lookupTable.add(ck);
|
||||||
}
|
}
|
||||||
if (nestedMappers) {
|
if (nestedMappers && val) {
|
||||||
sqlChildMapper(
|
sqlChildMapper(
|
||||||
doc,
|
doc,
|
||||||
docsByPk[pk][label as keyof P],
|
docsByPk[pk][label as keyof P],
|
||||||
|
|||||||
@@ -368,8 +368,9 @@ export const registerRoutes = async (
|
|||||||
const sarService = secretApprovalRequestServiceFactory({
|
const sarService = secretApprovalRequestServiceFactory({
|
||||||
permissionService,
|
permissionService,
|
||||||
folderDAL,
|
folderDAL,
|
||||||
sarSecretDAL,
|
secretTagDAL,
|
||||||
sarReviewerDAL,
|
secretApprovalRequestSecretDAL: sarSecretDAL,
|
||||||
|
secretApprovalRequestReviewerDAL: sarReviewerDAL,
|
||||||
secretVersionDAL,
|
secretVersionDAL,
|
||||||
secretBlindIndexDAL,
|
secretBlindIndexDAL,
|
||||||
secretApprovalRequestDAL,
|
secretApprovalRequestDAL,
|
||||||
|
|||||||
@@ -726,7 +726,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
skipMultilineEncoding,
|
skipMultilineEncoding,
|
||||||
secretKeyTag,
|
secretKeyTag,
|
||||||
secretKeyCiphertext,
|
secretKeyCiphertext,
|
||||||
secretKeyIV
|
secretKeyIV,
|
||||||
|
tagIds: tags
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,7 +99,6 @@ export const secretDALFactory = (db: TDbClient) => {
|
|||||||
.select(db.ref("color").withSchema(TableName.SecretTag).as("tagColor"))
|
.select(db.ref("color").withSchema(TableName.SecretTag).as("tagColor"))
|
||||||
.select(db.ref("slug").withSchema(TableName.SecretTag).as("tagSlug"))
|
.select(db.ref("slug").withSchema(TableName.SecretTag).as("tagSlug"))
|
||||||
.select(db.ref("name").withSchema(TableName.SecretTag).as("tagName"));
|
.select(db.ref("name").withSchema(TableName.SecretTag).as("tagName"));
|
||||||
console.log(JSON.stringify(secs, null, 4));
|
|
||||||
const data = sqlNestRelationships({
|
const data = sqlNestRelationships({
|
||||||
data: secs,
|
data: secs,
|
||||||
key: "id",
|
key: "id",
|
||||||
@@ -117,7 +116,6 @@ export const secretDALFactory = (db: TDbClient) => {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
console.log(JSON.stringify(data, null, 4));
|
|
||||||
return data;
|
return data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new DatabaseError({ error, name: "get all secret" });
|
throw new DatabaseError({ error, name: "get all secret" });
|
||||||
|
|||||||
@@ -164,19 +164,17 @@ export const secretServiceFactory = ({
|
|||||||
tags !== undefined ? { tags, secretId: newSecrets[i].id } : []
|
tags !== undefined ? { tags, secretId: newSecrets[i].id } : []
|
||||||
);
|
);
|
||||||
if (secsUpdatedTag.length) {
|
if (secsUpdatedTag.length) {
|
||||||
const delTags = await secretTagDAL.deleteTagsManySecret(
|
await secretTagDAL.deleteTagsManySecret(
|
||||||
projectId,
|
projectId,
|
||||||
secsUpdatedTag.map(({ secretId }) => secretId),
|
secsUpdatedTag.map(({ secretId }) => secretId),
|
||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
console.log(delTags);
|
|
||||||
const newSecretTags = secsUpdatedTag.flatMap(({ tags: secretTags = [], secretId }) =>
|
const newSecretTags = secsUpdatedTag.flatMap(({ tags: secretTags = [], secretId }) =>
|
||||||
secretTags.map((tag) => ({
|
secretTags.map((tag) => ({
|
||||||
[`${TableName.SecretTag}Id` as const]: tag,
|
[`${TableName.SecretTag}Id` as const]: tag,
|
||||||
[`${TableName.Secret}Id` as const]: secretId
|
[`${TableName.Secret}Id` as const]: secretId
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
console.log(newSecretTags);
|
|
||||||
if (newSecretTags.length) {
|
if (newSecretTags.length) {
|
||||||
const secTags = await secretTagDAL.saveTagsToSecret(newSecretTags, tx);
|
const secTags = await secretTagDAL.saveTagsToSecret(newSecretTags, tx);
|
||||||
const secVersionsGroupBySecId = groupBy(secretVersions, (i) => i.secretId);
|
const secVersionsGroupBySecId = groupBy(secretVersions, (i) => i.secretId);
|
||||||
|
|||||||
Reference in New Issue
Block a user