Improve Gitlab sync destination check and show projectId on duplicate destination

This commit is contained in:
Carlos Monastyrski
2025-10-03 01:00:30 -03:00
parent 76976ab85a
commit fb1d5ca257
7 changed files with 112 additions and 28 deletions
@@ -440,7 +440,10 @@ export const registerSyncSecretsEndpoints = <T extends TSecretSync, I extends TS
projectId: z.string().uuid()
}),
response: {
200: z.object({ hasDuplicate: z.boolean() })
200: z.object({
hasDuplicate: z.boolean(),
duplicateProjectId: z.string().uuid().optional()
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
@@ -713,7 +713,16 @@ export const secretSyncServiceFactory = ({
case SecretSync.DigitalOceanAppPlatform:
return ["appName"];
case SecretSync.GitLab:
return ["projectName", "shouldProtectSecrets", "shouldMaskSecrets", "shouldHideSecrets"];
return [
"projectName",
"shouldProtectSecrets",
"shouldMaskSecrets",
"shouldHideSecrets",
"targetEnvironment",
"groupName",
"groupId",
"projectId"
];
case SecretSync.Heroku:
return ["appName"];
case SecretSync.Netlify:
@@ -733,6 +742,34 @@ export const secretSyncServiceFactory = ({
}
};
const handleSpecialCaseDuplicateCheck = (
destination: SecretSync,
existingConfig: Record<string, unknown>,
newConfig: Record<string, unknown>
): boolean => {
switch (destination) {
case SecretSync.GitLab: {
const existingTargetEnv = existingConfig.targetEnvironment as string | undefined;
const newTargetEnv = newConfig.targetEnvironment as string | undefined;
// If either has wildcard '*', it conflicts with any targetEnvironment
if (existingTargetEnv === "*" || newTargetEnv === "*") {
return true;
}
return (
existingTargetEnv === newTargetEnv &&
((newConfig.scope as string) === "group"
? existingConfig.groupId === newConfig.groupId
: existingConfig.projectId === newConfig.projectId)
);
}
default:
// For other sync types, no special handling needed
return true;
}
};
const checkDuplicateDestination = async (
{ destination, destinationConfig, excludeSyncId, projectId }: TCheckDuplicateDestinationDTO,
actor: OrgServiceActor
@@ -753,7 +790,7 @@ export const secretSyncServiceFactory = ({
);
if (!destinationConfig || Object.keys(destinationConfig).length === 0) {
return { hasDuplicate: false };
return { hasDuplicate: false, duplicateProjectId: undefined };
}
try {
@@ -765,15 +802,27 @@ export const secretSyncServiceFactory = ({
}
try {
return deepEqualSkipFields(sync.destinationConfig, destinationConfig, skipFields);
const baseFieldsMatch = deepEqualSkipFields(sync.destinationConfig, destinationConfig, skipFields);
if (baseFieldsMatch) {
return handleSpecialCaseDuplicateCheck(
destination,
sync.destinationConfig as Record<string, unknown>,
destinationConfig
);
}
return false;
} catch {
return false;
}
});
return { hasDuplicate: duplicates.length > 0 };
const hasDuplicate = duplicates.length > 0;
return {
hasDuplicate,
duplicateProjectId: hasDuplicate ? duplicates[0].projectId : undefined
};
} catch (error) {
return { hasDuplicate: false };
return { hasDuplicate: false, duplicateProjectId: undefined };
}
};