Fix empty emails critical bug (#13465)
Fixes https://github.com/twentyhq/twenty/issues/13398 This bug was introduced by https://github.com/twentyhq/twenty/pull/13215 The emails were empty in scenarios where the user wasn't authenticated (reset passwords for instance) because in `hydrateGraphqlRequest` the information about the locale was added only if the user was authenticated `!this.isTokenPresent(request)`. So the locale was undefined making ` i18n.activate(undefined) ` fail silently resulting in an empty email.
This commit is contained in:
@ -478,4 +478,53 @@ describe('resolveObjectMetadataStandardOverride', () => {
|
||||
expect(mockI18n._).toHaveBeenCalledWith('auto.translation.id');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Undefined locale handling', () => {
|
||||
it('should use SOURCE_LOCALE fallback when locale is undefined for standard object', () => {
|
||||
const objectMetadata = {
|
||||
labelSingular: 'Standard Label',
|
||||
labelPlural: 'Standard Labels',
|
||||
description: 'Standard Description',
|
||||
icon: 'default-icon',
|
||||
isCustom: false,
|
||||
standardOverrides: {
|
||||
labelSingular: 'Source Override',
|
||||
},
|
||||
};
|
||||
|
||||
const result = resolveObjectMetadataStandardOverride(
|
||||
objectMetadata,
|
||||
'labelSingular',
|
||||
undefined,
|
||||
);
|
||||
|
||||
expect(result).toBe('Source Override');
|
||||
expect(mockGenerateMessageId).not.toHaveBeenCalled();
|
||||
expect(mockI18n._).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should fall back to auto translation when locale is undefined and no SOURCE_LOCALE override exists', () => {
|
||||
mockI18n._.mockReturnValue('Auto Translated Label');
|
||||
mockGenerateMessageId.mockReturnValue('auto.translation.id');
|
||||
|
||||
const objectMetadata = {
|
||||
labelSingular: 'Standard Label',
|
||||
labelPlural: 'Standard Labels',
|
||||
description: 'Standard Description',
|
||||
icon: 'default-icon',
|
||||
isCustom: false,
|
||||
standardOverrides: undefined,
|
||||
};
|
||||
|
||||
const result = resolveObjectMetadataStandardOverride(
|
||||
objectMetadata,
|
||||
'labelSingular',
|
||||
undefined,
|
||||
);
|
||||
|
||||
expect(result).toBe('Auto Translated Label');
|
||||
expect(mockGenerateMessageId).toHaveBeenCalledWith('Standard Label');
|
||||
expect(mockI18n._).toHaveBeenCalledWith('auto.translation.id');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -19,6 +19,8 @@ export const resolveObjectMetadataStandardOverride = (
|
||||
labelKey: 'labelPlural' | 'labelSingular' | 'description' | 'icon',
|
||||
locale: keyof typeof APP_LOCALES | undefined,
|
||||
): string => {
|
||||
const safeLocale = locale ?? SOURCE_LOCALE;
|
||||
|
||||
if (objectMetadata.isCustom) {
|
||||
return objectMetadata[labelKey] ?? '';
|
||||
}
|
||||
@ -32,11 +34,10 @@ export const resolveObjectMetadataStandardOverride = (
|
||||
|
||||
if (
|
||||
isDefined(objectMetadata.standardOverrides?.translations) &&
|
||||
isDefined(locale) &&
|
||||
labelKey !== 'icon'
|
||||
) {
|
||||
const translationValue =
|
||||
objectMetadata.standardOverrides.translations[locale]?.[labelKey];
|
||||
objectMetadata.standardOverrides.translations[safeLocale]?.[labelKey];
|
||||
|
||||
if (isDefined(translationValue)) {
|
||||
return translationValue;
|
||||
@ -44,7 +45,7 @@ export const resolveObjectMetadataStandardOverride = (
|
||||
}
|
||||
|
||||
if (
|
||||
locale === SOURCE_LOCALE &&
|
||||
safeLocale === SOURCE_LOCALE &&
|
||||
isNonEmptyString(objectMetadata.standardOverrides?.[labelKey])
|
||||
) {
|
||||
return objectMetadata.standardOverrides[labelKey] ?? '';
|
||||
|
||||
@ -128,6 +128,10 @@ export class MiddlewareService {
|
||||
|
||||
public async hydrateGraphqlRequest(request: Request) {
|
||||
if (!this.isTokenPresent(request)) {
|
||||
request.locale =
|
||||
(request.headers['x-locale'] as keyof typeof APP_LOCALES) ??
|
||||
SOURCE_LOCALE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user