Deprecate legacy encryption (#21831)

# Introduction
Still preserving the cross-upgrade flow

close https://github.com/twentyhq/core-team-issues/issues/2465


<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21831?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
This commit is contained in:
Paul Rastoin
2026-06-19 13:32:39 +02:00
committed by GitHub
parent 4de9f45015
commit 26db3f5735
32 changed files with 206 additions and 249 deletions
@@ -359,9 +359,10 @@ export class LogicFunctionExecutorService {
for (const variable of serverVariables) {
if (variable.encryptedValue !== '') {
envMap[variable.key] = this.secretEncryptionService.decryptVersioned(
variable.encryptedValue,
);
envMap[variable.key] =
this.secretEncryptionService.decryptVersionedOrThrow(
variable.encryptedValue,
);
}
}
@@ -12,7 +12,7 @@ describe('buildEnvVar', () => {
(value: string, opts?: { workspaceId?: string }) =>
`enc:v2:deadbeef:${value}|${opts?.workspaceId ?? 'instance'}`,
),
decryptVersioned: jest.fn(
decryptVersionedOrThrow: jest.fn(
(value: string, _opts?: { workspaceId?: string }) =>
value.replace(/^enc:v2:[0-9a-f]+:/, '').replace(/\|.*$/, ''),
),
@@ -79,9 +79,9 @@ describe('buildEnvVar', () => {
API_SECRET: 'secret-123',
DEBUG: 'true',
});
expect(mockSecretEncryptionService.decryptVersioned).toHaveBeenCalledTimes(
3,
);
expect(
mockSecretEncryptionService.decryptVersionedOrThrow,
).toHaveBeenCalledTimes(3);
});
it('routes each secret variable to its own workspace HKDF context', () => {
@@ -116,14 +116,16 @@ describe('buildEnvVar', () => {
buildEnvVar(flatVariables, mockSecretEncryptionService);
expect(mockSecretEncryptionService.decryptVersioned).toHaveBeenCalledWith(
`enc:v2:deadbeef:value-a|${workspaceA}`,
{ workspaceId: workspaceA },
);
expect(mockSecretEncryptionService.decryptVersioned).toHaveBeenCalledWith(
`enc:v2:deadbeef:value-b|${workspaceB}`,
{ workspaceId: workspaceB },
);
expect(
mockSecretEncryptionService.decryptVersionedOrThrow,
).toHaveBeenCalledWith(`enc:v2:deadbeef:value-a|${workspaceA}`, {
workspaceId: workspaceA,
});
expect(
mockSecretEncryptionService.decryptVersionedOrThrow,
).toHaveBeenCalledWith(`enc:v2:deadbeef:value-b|${workspaceB}`, {
workspaceId: workspaceB,
});
});
it('should handle null or undefined values', () => {
@@ -16,7 +16,7 @@ export const buildEnvVar = (
// the else branch into an invariant violation for non-empty values.
acc[flatApplicationVariable.key] =
isNonEmptyString(value) && isEncryptedString(value)
? secretEncryptionService.decryptVersioned(value, {
? secretEncryptionService.decryptVersionedOrThrow(value, {
workspaceId: flatApplicationVariable.workspaceId,
})
: value;