Lowercase email (#17775)
Fixes https://github.com/twentyhq/core-team-issues/issues/120 #16976 Partially related to #17711 Frontend check surprisingly was one-liner covering both email input and import files Migration script will be done in next commit --------- Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
This commit is contained in:
+5
-4
@@ -120,10 +120,11 @@ export class DataArgProcessor {
|
||||
);
|
||||
}
|
||||
|
||||
const fieldMetadata = findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId: fieldMetadataId,
|
||||
flatEntityMaps: flatFieldMetadataMaps,
|
||||
});
|
||||
const fieldMetadata =
|
||||
findFlatEntityByIdInFlatEntityMaps<FlatFieldMetadata>({
|
||||
flatEntityId: fieldMetadataId,
|
||||
flatEntityMaps: flatFieldMetadataMaps,
|
||||
});
|
||||
|
||||
if (!fieldMetadata) {
|
||||
throw new CommonQueryRunnerException(
|
||||
|
||||
+31
@@ -83,5 +83,36 @@ describe('validateEmailsFieldOrThrow', () => {
|
||||
validateEmailsFieldOrThrow(emailsValue, 'testField'),
|
||||
).toThrow(CommonQueryRunnerException);
|
||||
});
|
||||
|
||||
it('should throw when additionalEmails is an invalid string', () => {
|
||||
const emailsValue = {
|
||||
additionalEmails: 'ADDITIONALexample.com',
|
||||
};
|
||||
|
||||
expect(() =>
|
||||
validateEmailsFieldOrThrow(emailsValue, 'testField'),
|
||||
).toThrow(CommonQueryRunnerException);
|
||||
});
|
||||
|
||||
it('should throw when primaryEmail is invalid but additionalEmails are valid', () => {
|
||||
const emailsValue = {
|
||||
primaryEmail: 'Primaryexample.com',
|
||||
additionalEmails: ['additional@example.com'],
|
||||
};
|
||||
|
||||
expect(() =>
|
||||
validateEmailsFieldOrThrow(emailsValue, 'testField'),
|
||||
).toThrow(CommonQueryRunnerException);
|
||||
});
|
||||
|
||||
it('should throw when one of additionalEmails is invalid', () => {
|
||||
const emailsValue = {
|
||||
additionalEmails: ['Additional1example.com', 'additional2@example.com'],
|
||||
};
|
||||
|
||||
expect(() =>
|
||||
validateEmailsFieldOrThrow(emailsValue, 'testField'),
|
||||
).toThrow(CommonQueryRunnerException);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
import { inspect } from 'util';
|
||||
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { isNull } from '@sniptt/guards';
|
||||
|
||||
import { validateEmailsPrimaryEmailSubfieldOrThrow } from 'src/engine/api/common/common-args-processors/data-arg-processor/validator-utils/validate-emails-primary-email-subfield-or-throw.util';
|
||||
import {
|
||||
CommonQueryRunnerException,
|
||||
CommonQueryRunnerExceptionCode,
|
||||
} from 'src/engine/api/common/common-query-runners/errors/common-query-runner.exception';
|
||||
|
||||
export const validateEmailsAdditionalEmailsSubfieldOrThrow = (
|
||||
value: unknown,
|
||||
fieldName: string,
|
||||
): string | string[] | null => {
|
||||
if (isNull(value)) return null;
|
||||
|
||||
if (typeof value === 'string') {
|
||||
return validateEmailsPrimaryEmailSubfieldOrThrow(value, fieldName);
|
||||
}
|
||||
|
||||
if (
|
||||
!Array.isArray(value) ||
|
||||
value.some((item) =>
|
||||
isNull(validateEmailsPrimaryEmailSubfieldOrThrow(item, fieldName)),
|
||||
)
|
||||
) {
|
||||
const inspectedValue = inspect(value);
|
||||
|
||||
throw new CommonQueryRunnerException(
|
||||
`Invalid value ${inspectedValue} for field "${fieldName} - Array values need to be string"`,
|
||||
CommonQueryRunnerExceptionCode.INVALID_ARGS_DATA,
|
||||
{ userFriendlyMessage: msg`Invalid value: "${inspectedValue}"` },
|
||||
);
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
+10
-4
@@ -1,9 +1,9 @@
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { isNull } from '@sniptt/guards';
|
||||
|
||||
import { validateArrayFieldOrThrow } from 'src/engine/api/common/common-args-processors/data-arg-processor/validator-utils/validate-array-field-or-throw.util';
|
||||
import { validateEmailsAdditionalEmailsSubfieldOrThrow } from 'src/engine/api/common/common-args-processors/data-arg-processor/validator-utils/validate-emails-additional-emails-subfield-or-throw.util';
|
||||
import { validateEmailsPrimaryEmailSubfieldOrThrow } from 'src/engine/api/common/common-args-processors/data-arg-processor/validator-utils/validate-emails-primary-email-subfield-or-throw.util';
|
||||
import { validateRawJsonFieldOrThrow } from 'src/engine/api/common/common-args-processors/data-arg-processor/validator-utils/validate-raw-json-field-or-throw.util';
|
||||
import { validateTextFieldOrThrow } from 'src/engine/api/common/common-args-processors/data-arg-processor/validator-utils/validate-text-field-or-throw.util';
|
||||
import {
|
||||
CommonQueryRunnerException,
|
||||
CommonQueryRunnerExceptionCode,
|
||||
@@ -23,10 +23,16 @@ export const validateEmailsFieldOrThrow = (
|
||||
for (const [subField, subFieldValue] of Object.entries(preValidatedValue)) {
|
||||
switch (subField) {
|
||||
case 'primaryEmail':
|
||||
validateTextFieldOrThrow(subFieldValue, `${fieldName}.${subField}`);
|
||||
validateEmailsPrimaryEmailSubfieldOrThrow(
|
||||
subFieldValue,
|
||||
`${fieldName}.${subField}`,
|
||||
);
|
||||
break;
|
||||
case 'additionalEmails':
|
||||
validateArrayFieldOrThrow(subFieldValue, `${fieldName}.${subField}`);
|
||||
validateEmailsAdditionalEmailsSubfieldOrThrow(
|
||||
subFieldValue,
|
||||
`${fieldName}.${subField}`,
|
||||
);
|
||||
break;
|
||||
default:
|
||||
throw new CommonQueryRunnerException(
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
import { inspect } from 'util';
|
||||
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { isNonEmptyString, isNull } from '@sniptt/guards';
|
||||
import { z } from 'zod';
|
||||
|
||||
import {
|
||||
CommonQueryRunnerException,
|
||||
CommonQueryRunnerExceptionCode,
|
||||
} from 'src/engine/api/common/common-query-runners/errors/common-query-runner.exception';
|
||||
|
||||
export const validateEmailsPrimaryEmailSubfieldOrThrow = (
|
||||
value: unknown,
|
||||
fieldName: string,
|
||||
): string | null => {
|
||||
if (isNull(value)) return null;
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
const inspectedValue = inspect(value);
|
||||
|
||||
throw new CommonQueryRunnerException(
|
||||
`Invalid string value ${inspectedValue} for email field "${fieldName}"`,
|
||||
CommonQueryRunnerExceptionCode.INVALID_ARGS_DATA,
|
||||
{ userFriendlyMessage: msg`Invalid value: "${inspectedValue}"` },
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
!z.email({ pattern: z.regexes.unicodeEmail }).safeParse(value).success &&
|
||||
isNonEmptyString(value)
|
||||
) {
|
||||
const inspectedValue = inspect(value);
|
||||
|
||||
throw new CommonQueryRunnerException(
|
||||
`Invalid string value ${inspectedValue} for email field "${fieldName}"`,
|
||||
CommonQueryRunnerExceptionCode.INVALID_ARGS_DATA,
|
||||
{ userFriendlyMessage: msg`Invalid value: "${inspectedValue}"` },
|
||||
);
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
Reference in New Issue
Block a user