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
@@ -133,7 +133,7 @@ export class ColumnRotationSiteHandler<
: undefined;
try {
const plaintext = this.secretEncryptionService.decryptVersioned(
const plaintext = this.secretEncryptionService.decryptVersionedOrThrow(
currentValue,
cryptoOptions,
);
@@ -16,11 +16,6 @@ import {
type EncryptedImapSmtpCaldavParams,
type ImapSmtpCaldavParams,
} from 'src/engine/core-modules/imap-smtp-caldav-connection/types/imap-smtp-caldav-connection.type';
import { SECRET_ENCRYPTION_ENVELOPE_V2_PREFIX } from 'src/engine/core-modules/secret-encryption/constants/secret-encryption.constant';
import {
SecretEncryptionException,
SecretEncryptionExceptionCode,
} from 'src/engine/core-modules/secret-encryption/exceptions/secret-encryption.exception';
import { SecretEncryptionService } from 'src/engine/core-modules/secret-encryption/secret-encryption.service';
import { ConnectedAccountEntity } from 'src/engine/metadata-modules/connected-account/entities/connected-account.entity';
@@ -147,16 +142,7 @@ export class ConnectionParametersRotationHandler extends SecretEncryptionRotatio
continue;
}
// Refuse non-enc:v2 values up front: decryptVersioned would otherwise
// fall through to unauthenticated legacy CTR and corrupt the password.
if (!params.password.startsWith(SECRET_ENCRYPTION_ENVELOPE_V2_PREFIX)) {
throw new SecretEncryptionException(
`${protocol} password is not a versioned envelope (expected '${SECRET_ENCRYPTION_ENVELOPE_V2_PREFIX}…'), refusing to rotate.`,
SecretEncryptionExceptionCode.MALFORMED_ENVELOPE,
);
}
const plaintext = this.secretEncryptionService.decryptVersioned(
const plaintext = this.secretEncryptionService.decryptVersionedOrThrow(
params.password,
{ workspaceId },
);
@@ -118,7 +118,8 @@ export class SensitiveConfigStorageRotationHandler extends SecretEncryptionRotat
}
try {
const plaintext = this.secretEncryptionService.decryptVersioned(rawValue);
const plaintext =
this.secretEncryptionService.decryptVersionedOrThrow(rawValue);
const reEncrypted =
this.secretEncryptionService.encryptVersioned(plaintext);
@@ -85,10 +85,11 @@ export class EncryptApplicationVariableSlowInstanceCommand
if (looksLikeLegacyCtrCiphertext(row.value)) {
try {
plaintext = this.secretEncryptionService.decryptVersioned(
row.value as EncryptedString,
{ workspaceId: row.workspaceId },
);
plaintext =
this.secretEncryptionService.legacyDecryptVersionedWithFallback(
row.value as EncryptedString,
{ workspaceId: row.workspaceId },
);
} catch (error) {
this.logger.warn(
`applicationVariable row ${row.id} value not valid ciphertext; treating as plaintext. ${
@@ -57,9 +57,10 @@ export class EncryptApplicationRegistrationVariableSlowInstanceCommand
continue;
}
const plaintext = this.secretEncryptionService.decryptVersioned(
row.encryptedValue as EncryptedString,
);
const plaintext =
this.secretEncryptionService.legacyDecryptVersionedWithFallback(
row.encryptedValue as EncryptedString,
);
if (!isDefined(plaintext)) {
continue;
@@ -54,9 +54,10 @@ export class EncryptSigningKeyPrivateKeysSlowInstanceCommand implements SlowInst
continue;
}
const plaintext = this.secretEncryptionService.decryptVersioned(
row.privateKey as EncryptedString,
);
const plaintext =
this.secretEncryptionService.legacyDecryptVersionedWithFallback(
row.privateKey as EncryptedString,
);
if (!isDefined(plaintext)) {
continue;
@@ -57,9 +57,10 @@ export class EncryptSensitiveConfigStorageSlowInstanceCommand implements SlowIns
continue;
}
const plaintext = this.secretEncryptionService.decryptVersioned(
rawValue as EncryptedString,
);
const plaintext =
this.secretEncryptionService.legacyDecryptVersionedWithFallback(
rawValue as EncryptedString,
);
if (!isDefined(plaintext)) {
continue;