fix(server): encrypt token post refresh (#20819)

# Introduction
Jobs were refreshing token and returning them as plain text, resulting
to underlying code flow failure as expecting encrypted tokens

## Next
We should define a strong typescript signature to avoid such things to
happen again, or least have an explicit naming
This commit is contained in:
Paul Rastoin
2026-05-21 18:53:03 +02:00
committed by GitHub
parent 0bfcd9a701
commit 3c91f3f276
4 changed files with 84 additions and 95 deletions
@@ -6,6 +6,7 @@ import { ApplicationConnectionsController } from 'src/engine/core-modules/applic
import { ApplicationConnectionsListService } from 'src/engine/core-modules/application/connection-provider/connections/services/application-connections-list.service';
import { TokenModule } from 'src/engine/core-modules/auth/token/token.module';
import { ConnectedAccountEntity } from 'src/engine/metadata-modules/connected-account/entities/connected-account.entity';
import { ConnectedAccountTokenEncryptionModule } from 'src/engine/metadata-modules/connected-account/services/connected-account-token-encryption.module';
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
import { RefreshTokensManagerModule } from 'src/modules/connected-account/refresh-tokens-manager/connected-account-refresh-tokens-manager.module';
@@ -22,6 +23,7 @@ import { RefreshTokensManagerModule } from 'src/modules/connected-account/refres
TokenModule,
WorkspaceCacheStorageModule,
RefreshTokensManagerModule,
ConnectedAccountTokenEncryptionModule,
],
providers: [ApplicationConnectionsListService],
controllers: [ApplicationConnectionsController],
@@ -9,6 +9,7 @@ import { isDefined } from 'twenty-shared/utils';
import { ConnectionProviderEntity } from 'src/engine/core-modules/application/connection-provider/connection-provider.entity';
import { type AppConnectionDto } from 'src/engine/core-modules/application/connection-provider/connections/dtos/app-connection.dto';
import { ConnectedAccountEntity } from 'src/engine/metadata-modules/connected-account/entities/connected-account.entity';
import { ConnectedAccountTokenEncryptionService } from 'src/engine/metadata-modules/connected-account/services/connected-account-token-encryption.service';
import { ConnectedAccountRefreshTokensService } from 'src/modules/connected-account/refresh-tokens-manager/services/connected-account-refresh-tokens.service';
type ListArgs = {
@@ -38,6 +39,7 @@ export class ApplicationConnectionsListService {
constructor(
private readonly refreshTokensService: ConnectedAccountRefreshTokensService,
private readonly connectedAccountTokenEncryptionService: ConnectedAccountTokenEncryptionService,
@InjectRepository(ConnectedAccountEntity)
private readonly connectedAccountRepository: Repository<ConnectedAccountEntity>,
@InjectRepository(ConnectionProviderEntity)
@@ -207,7 +209,7 @@ export class ApplicationConnectionsListService {
}
try {
const tokens = await this.refreshTokensService.resolveTokens(
const encryptedTokens = await this.refreshTokensService.resolveTokens(
account,
workspaceId,
);
@@ -219,7 +221,10 @@ export class ApplicationConnectionsListService {
handle: account.handle,
visibility: account.visibility as 'user' | 'workspace',
userWorkspaceId: account.userWorkspaceId,
accessToken: tokens.accessToken,
accessToken: this.connectedAccountTokenEncryptionService.decrypt({
ciphertext: encryptedTokens.accessToken,
workspaceId,
}),
scopes: account.scopes ?? provider.oauthConfig?.scopes ?? [],
authFailedAt: account.authFailedAt?.toISOString() ?? null,
};