feat: resolved personal secret breaking secret replication

This commit is contained in:
=
2024-05-31 23:10:02 +05:30
parent 2d0d90785f
commit 531d3751a8
2 changed files with 17 additions and 9 deletions
@@ -1,7 +1,7 @@
import { Knex } from "knex"; import { Knex } from "knex";
import { TDbClient } from "@app/db"; import { TDbClient } from "@app/db";
import { TableName, TSecretVersions } from "@app/db/schemas"; import { SecretType, TableName, TSecretVersions } from "@app/db/schemas";
import { ormify, selectAllTableCols } from "@app/lib/knex"; import { ormify, selectAllTableCols } from "@app/lib/knex";
export type TSecretReplicationDALFactory = ReturnType<typeof secretReplicationDALFactory>; export type TSecretReplicationDALFactory = ReturnType<typeof secretReplicationDALFactory>;
@@ -9,7 +9,10 @@ export type TSecretReplicationDALFactory = ReturnType<typeof secretReplicationDA
export const secretReplicationDALFactory = (db: TDbClient) => { export const secretReplicationDALFactory = (db: TDbClient) => {
const orm = ormify(db, TableName.SecretVersion); const orm = ormify(db, TableName.SecretVersion);
const findSecrets = async (filter: { folderId: string; secrets: { id: string; version: number }[] }, tx?: Knex) => { const findSecretVersions = async (
filter: { folderId: string; secrets: { id: string; version: number }[] },
tx?: Knex
) => {
if (!filter.secrets) return []; if (!filter.secrets) return [];
const sqlRawDocs = await (tx || db)(TableName.SecretVersion) const sqlRawDocs = await (tx || db)(TableName.SecretVersion)
@@ -18,7 +21,8 @@ export const secretReplicationDALFactory = (db: TDbClient) => {
filter.secrets.forEach((el) => { filter.secrets.forEach((el) => {
void bd.orWhere({ void bd.orWhere({
[`${TableName.SecretVersion}.secretId` as "secretId"]: el.id, [`${TableName.SecretVersion}.secretId` as "secretId"]: el.id,
[`${TableName.SecretVersion}.version` as "version"]: el.version [`${TableName.SecretVersion}.version` as "version"]: el.version,
[`${TableName.SecretVersion}.type` as "type"]: SecretType.Shared
}); });
}); });
}) })
@@ -39,7 +43,7 @@ export const secretReplicationDALFactory = (db: TDbClient) => {
}; };
return { return {
findSecrets, findSecretVersions,
...orm ...orm
}; };
}; };
@@ -80,13 +80,16 @@ export const secretReplicationServiceFactory = ({
if (!secretImports.length || !secrets.length) return; if (!secretImports.length || !secrets.length) return;
// unfiltered secrets to be replicated // unfiltered secrets to be replicated
const toBeReplicatedSecrets = await secretReplicationDAL.findSecrets({ folderId, secrets }); const toBeReplicatedSecrets = await secretReplicationDAL.findSecretVersions({ folderId, secrets });
const replicatedSecrets = toBeReplicatedSecrets.filter( const replicatedSecrets = toBeReplicatedSecrets.filter(
({ version, latestReplicatedVersion, secretBlindIndex }) => ({ version, latestReplicatedVersion, secretBlindIndex }) =>
secretBlindIndex && (version === 1 || latestReplicatedVersion <= version) secretBlindIndex && (version === 1 || latestReplicatedVersion <= version)
); );
const replicatedSecretsGroupBySecretId = groupBy(replicatedSecrets, (i) => i.secretId); const replicatedSecretsGroupBySecretId = groupBy(replicatedSecrets, (i) => i.secretId);
// this is to filter out personal secrets
const sanitizedSecrets = secrets.filter(({ id }) => Object.hasOwn(replicatedSecretsGroupBySecretId, id));
if (!sanitizedSecrets.length) return;
const lock = await keyStore.acquireLock( const lock = await keyStore.acquireLock(
replicatedSecrets.map(({ id }) => id), replicatedSecrets.map(({ id }) => id),
5000 5000
@@ -118,20 +121,20 @@ export const secretReplicationServiceFactory = ({
}); });
const localSecretsGroupedByBlindIndex = groupBy(localSecrets, (i) => i.secretBlindIndex as string); const localSecretsGroupedByBlindIndex = groupBy(localSecrets, (i) => i.secretBlindIndex as string);
const locallyCreatedSecrets = secrets.filter(({ operation, id }) => { const locallyCreatedSecrets = sanitizedSecrets.filter(({ operation, id }) => {
return ( return (
(operation === SecretOperations.Create || operation === SecretOperations.Update) && (operation === SecretOperations.Create || operation === SecretOperations.Update) &&
!localSecretsGroupedByBlindIndex[replicatedSecretsGroupBySecretId[id][0].secretBlindIndex as string]?.[0] !localSecretsGroupedByBlindIndex[replicatedSecretsGroupBySecretId[id][0].secretBlindIndex as string]?.[0]
); );
}); });
const locallyUpdatedSecrets = secrets.filter( const locallyUpdatedSecrets = sanitizedSecrets.filter(
({ operation, id }) => ({ operation, id }) =>
(operation === SecretOperations.Create || operation === SecretOperations.Update) && (operation === SecretOperations.Create || operation === SecretOperations.Update) &&
localSecretsGroupedByBlindIndex[replicatedSecretsGroupBySecretId[id][0].secretBlindIndex as string]?.[0] localSecretsGroupedByBlindIndex[replicatedSecretsGroupBySecretId[id][0].secretBlindIndex as string]?.[0]
); );
const locallyDeletedSecrets = secrets.filter( const locallyDeletedSecrets = sanitizedSecrets.filter(
({ operation, id }) => ({ operation, id }) =>
operation === SecretOperations.Delete && operation === SecretOperations.Delete &&
Boolean(replicatedSecretsGroupBySecretId[id]?.[0]?.secretBlindIndex) && Boolean(replicatedSecretsGroupBySecretId[id]?.[0]?.secretBlindIndex) &&
@@ -333,6 +336,7 @@ export const secretReplicationServiceFactory = ({
/* eslint-enable no-await-in-loop */ /* eslint-enable no-await-in-loop */
} finally { } finally {
await lock.release(); await lock.release();
logger.info(job.data, "Replication finished");
} }
}); });