feat: Add compatibility for MongoDB Atlas Serverless and AWS Amazon DocumentDB with collation options enableCollationCaseComparison, transformEmailToLowercase, transformUsernameToLowercase (#8805)

This commit is contained in:
Mattia Faraci
2023-11-13 23:32:47 +01:00
committed by GitHub
parent 80b987d00d
commit 09fbeebba8
5 changed files with 323 additions and 14 deletions

View File

@@ -368,6 +368,22 @@ const relationSchema = {
fields: { relatedId: { type: 'String' }, owningId: { type: 'String' } },
};
const convertEmailToLowercase = (object, className, options) => {
if (className === '_User' && options.convertEmailToLowercase) {
if (typeof object['email'] === 'string') {
object['email'] = object['email'].toLowerCase();
}
}
};
const convertUsernameToLowercase = (object, className, options) => {
if (className === '_User' && options.convertUsernameToLowercase) {
if (typeof object['username'] === 'string') {
object['username'] = object['username'].toLowerCase();
}
}
};
class DatabaseController {
adapter: StorageAdapter;
schemaCache: any;
@@ -573,6 +589,8 @@ class DatabaseController {
}
}
update = transformObjectACL(update);
convertEmailToLowercase(update, className, this.options);
convertUsernameToLowercase(update, className, this.options);
transformAuthData(className, update, schema);
if (validateOnly) {
return this.adapter.find(className, schema, query, {}).then(result => {
@@ -822,6 +840,8 @@ class DatabaseController {
const originalObject = object;
object = transformObjectACL(object);
convertEmailToLowercase(object, className, this.options);
convertUsernameToLowercase(object, className, this.options);
object.createdAt = { iso: object.createdAt, __type: 'Date' };
object.updatedAt = { iso: object.updatedAt, __type: 'Date' };
@@ -1215,7 +1235,7 @@ class DatabaseController {
keys,
readPreference,
hint,
caseInsensitive,
caseInsensitive: this.options.enableCollationCaseComparison ? false : caseInsensitive,
explain,
};
Object.keys(sort).forEach(fieldName => {
@@ -1719,25 +1739,27 @@ class DatabaseController {
throw error;
});
await this.adapter
.ensureIndex('_User', requiredUserFields, ['username'], 'case_insensitive_username', true)
.catch(error => {
logger.warn('Unable to create case insensitive username index: ', error);
throw error;
});
if (!this.options.enableCollationCaseComparison) {
await this.adapter
.ensureIndex('_User', requiredUserFields, ['username'], 'case_insensitive_username', true)
.catch(error => {
logger.warn('Unable to create case insensitive username index: ', error);
throw error;
});
await this.adapter
.ensureIndex('_User', requiredUserFields, ['email'], 'case_insensitive_email', true)
.catch(error => {
logger.warn('Unable to create case insensitive email index: ', error);
throw error;
});
}
await this.adapter.ensureUniqueness('_User', requiredUserFields, ['email']).catch(error => {
logger.warn('Unable to ensure uniqueness for user email addresses: ', error);
throw error;
});
await this.adapter
.ensureIndex('_User', requiredUserFields, ['email'], 'case_insensitive_email', true)
.catch(error => {
logger.warn('Unable to create case insensitive email index: ', error);
throw error;
});
await this.adapter.ensureUniqueness('_Role', requiredRoleFields, ['name']).catch(error => {
logger.warn('Unable to ensure uniqueness for role name: ', error);
throw error;