From fb30e4380eb3aa0bc8d7a75a34617423bb179333 Mon Sep 17 00:00:00 2001 From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com> Date: Sat, 1 Nov 2025 14:20:44 +0100 Subject: [PATCH 1/5] options --- .../Storage/Mongo/MongoStorageAdapter.js | 15 ++++++++-- src/Options/Definitions.js | 28 +++++++++++++++++++ src/Options/docs.js | 4 +++ src/Options/index.js | 12 ++++++++ 4 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js index ad5a69ea70..12be75560a 100644 --- a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -154,8 +154,19 @@ export class MongoStorageAdapter implements StorageAdapter { this.enableSchemaHooks = !!mongoOptions.enableSchemaHooks; this.schemaCacheTtl = mongoOptions.schemaCacheTtl; this.disableIndexFieldValidation = !!mongoOptions.disableIndexFieldValidation; - for (const key of ['enableSchemaHooks', 'schemaCacheTtl', 'maxTimeMS', 'disableIndexFieldValidation']) { - delete mongoOptions[key]; + // Remove Parse Server-specific options that should not be passed to MongoDB client + // Note: We only delete from this._mongoOptions, not from the original mongoOptions object, + // because other components (like DatabaseController) need access to these options + for (const key of [ + 'enableSchemaHooks', + 'schemaCacheTtl', + 'maxTimeMS', + 'disableIndexFieldValidation', + 'createIndexUsername', + 'createIndexEmail', + 'createIndexEmailVerifyToken', + 'createIndexPasswordResetToken', + ]) { delete this._mongoOptions[key]; } } diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js index 205c35fa77..eef946302d 100644 --- a/src/Options/Definitions.js +++ b/src/Options/Definitions.js @@ -1101,6 +1101,34 @@ module.exports.DatabaseOptions = { 'The MongoDB driver option to specify the amount of time, in milliseconds, to wait to establish a single TCP socket connection to the server before raising an error. Specifying 0 disables the connection timeout.', action: parsers.numberParser('connectTimeoutMS'), }, + createIndexEmail: { + env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_EMAIL', + help: + 'Set to `true` to automatically create indexes on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index.', + action: parsers.booleanParser, + default: true, + }, + createIndexEmailVerifyToken: { + env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_EMAIL_VERIFY_TOKEN', + help: + 'Set to `true` to automatically create an index on the _email_verify_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index.', + action: parsers.booleanParser, + default: true, + }, + createIndexPasswordResetToken: { + env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_PASSWORD_RESET_TOKEN', + help: + 'Set to `true` to automatically create an index on the _perishable_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index.', + action: parsers.booleanParser, + default: true, + }, + createIndexUsername: { + env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_USERNAME', + help: + 'Set to `true` to automatically create indexes on the username field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index.', + action: parsers.booleanParser, + default: true, + }, disableIndexFieldValidation: { env: 'PARSE_SERVER_DATABASE_DISABLE_INDEX_FIELD_VALIDATION', help: diff --git a/src/Options/docs.js b/src/Options/docs.js index dde5942500..9826f36fa9 100644 --- a/src/Options/docs.js +++ b/src/Options/docs.js @@ -243,6 +243,10 @@ * @property {Boolean} autoSelectFamily The MongoDB driver option to set whether the socket attempts to connect to IPv6 and IPv4 addresses until a connection is established. If available, the driver will select the first IPv6 address. * @property {Number} autoSelectFamilyAttemptTimeout The MongoDB driver option to specify the amount of time in milliseconds to wait for a connection attempt to finish before trying the next address when using the autoSelectFamily option. If set to a positive integer less than 10, the value 10 is used instead. * @property {Number} connectTimeoutMS The MongoDB driver option to specify the amount of time, in milliseconds, to wait to establish a single TCP socket connection to the server before raising an error. Specifying 0 disables the connection timeout. + * @property {Boolean} createIndexEmail Set to `true` to automatically create indexes on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index. + * @property {Boolean} createIndexEmailVerifyToken Set to `true` to automatically create an index on the _email_verify_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index. + * @property {Boolean} createIndexPasswordResetToken Set to `true` to automatically create an index on the _perishable_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index. + * @property {Boolean} createIndexUsername Set to `true` to automatically create indexes on the username field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index. * @property {Boolean} disableIndexFieldValidation Set to `true` to disable validation of index fields. When disabled, indexes can be created even if the fields do not exist in the schema. This can be useful when creating indexes on fields that will be added later. * @property {Boolean} enableSchemaHooks Enables database real-time hooks to update single schema cache. Set to `true` if using multiple Parse Servers instances connected to the same database. Failing to do so will cause a schema change to not propagate to all instances and re-syncing will only happen when the instances restart. To use this feature with MongoDB, a replica set cluster with [change stream](https://docs.mongodb.com/manual/changeStreams/#availability) support is required. * @property {Number} maxPoolSize The MongoDB driver option to set the maximum number of opened, cached, ready-to-use database connections maintained by the driver. diff --git a/src/Options/index.js b/src/Options/index.js index ff8287b86b..2f6ad11dff 100644 --- a/src/Options/index.js +++ b/src/Options/index.js @@ -632,6 +632,18 @@ export interface DatabaseOptions { autoSelectFamily: ?boolean; /* The MongoDB driver option to specify the amount of time in milliseconds to wait for a connection attempt to finish before trying the next address when using the autoSelectFamily option. If set to a positive integer less than 10, the value 10 is used instead. */ autoSelectFamilyAttemptTimeout: ?number; + /* Set to `true` to automatically create indexes on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index. + :DEFAULT: true */ + createIndexEmail: ?boolean; + /* Set to `true` to automatically create an index on the _email_verify_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index. + :DEFAULT: true */ + createIndexEmailVerifyToken: ?boolean; + /* Set to `true` to automatically create an index on the _perishable_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index. + :DEFAULT: true */ + createIndexPasswordResetToken: ?boolean; + /* Set to `true` to automatically create indexes on the username field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index. + :DEFAULT: true */ + createIndexUsername: ?boolean; /* Set to `true` to disable validation of index fields. When disabled, indexes can be created even if the fields do not exist in the schema. This can be useful when creating indexes on fields that will be added later. */ disableIndexFieldValidation: ?boolean; } From 16d62ed99d619ddc0b6647a7bcddd5014e73e74d Mon Sep 17 00:00:00 2001 From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com> Date: Sat, 1 Nov 2025 14:41:53 +0100 Subject: [PATCH 2/5] options --- .../Storage/Mongo/MongoStorageAdapter.js | 3 + src/Controllers/DatabaseController.js | 74 +++++++++++-------- src/Options/Definitions.js | 29 +++++++- src/Options/docs.js | 11 ++- src/Options/index.js | 17 ++++- 5 files changed, 93 insertions(+), 41 deletions(-) diff --git a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js index 12be75560a..49a96fbf9a 100644 --- a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -163,9 +163,12 @@ export class MongoStorageAdapter implements StorageAdapter { 'maxTimeMS', 'disableIndexFieldValidation', 'createIndexUsername', + 'createIndexUsernameCaseInsensitive', 'createIndexEmail', + 'createIndexEmailCaseInsensitive', 'createIndexEmailVerifyToken', 'createIndexPasswordResetToken', + 'createIndexRoleName', ]) { delete this._mongoOptions[key]; } diff --git a/src/Controllers/DatabaseController.js b/src/Controllers/DatabaseController.js index e3b5cc210a..8fabd17372 100644 --- a/src/Controllers/DatabaseController.js +++ b/src/Controllers/DatabaseController.js @@ -1738,50 +1738,66 @@ class DatabaseController { await this.loadSchema().then(schema => schema.enforceClassExists('_Role')); await this.loadSchema().then(schema => schema.enforceClassExists('_Idempotency')); - await this.adapter.ensureUniqueness('_User', requiredUserFields, ['username']).catch(error => { - logger.warn('Unable to ensure uniqueness for usernames: ', error); - throw error; - }); + const databaseOptions = this.options.databaseOptions || {}; + + if (databaseOptions.createIndexUsername) { + await this.adapter.ensureUniqueness('_User', requiredUserFields, ['username']).catch(error => { + logger.warn('Unable to ensure uniqueness for usernames: ', error); + throw error; + }); + } if (!this.options.enableCollationCaseComparison) { + if (databaseOptions.createIndexUsernameCaseInsensitive) { + 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 (databaseOptions.createIndexEmailCaseInsensitive) { + 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; + }); + } + } + + if (databaseOptions.createIndexEmail) { + await this.adapter.ensureUniqueness('_User', requiredUserFields, ['email']).catch(error => { + logger.warn('Unable to ensure uniqueness for user email addresses: ', error); + throw error; + }); + } + + if (databaseOptions.createIndexEmailVerifyToken) { await this.adapter - .ensureIndex('_User', requiredUserFields, ['username'], 'case_insensitive_username', true) + .ensureIndex('_User', requiredUserFields, ['_email_verify_token'], '_email_verify_token', false) .catch(error => { - logger.warn('Unable to create case insensitive username index: ', error); + logger.warn('Unable to create index for email verification token: ', error); throw error; }); + } + if (databaseOptions.createIndexPasswordResetToken) { await this.adapter - .ensureIndex('_User', requiredUserFields, ['email'], 'case_insensitive_email', true) + .ensureIndex('_User', requiredUserFields, ['_perishable_token'], '_perishable_token', false) .catch(error => { - logger.warn('Unable to create case insensitive email index: ', error); + logger.warn('Unable to create index for password reset token: ', 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_verify_token'], '_email_verify_token', false) - .catch(error => { - logger.warn('Unable to create index for email verification token: ', error); - throw error; - }); - - await this.adapter - .ensureIndex('_User', requiredUserFields, ['_perishable_token'], '_perishable_token', false) - .catch(error => { - logger.warn('Unable to create index for password reset token: ', error); + if (databaseOptions.createIndexRoleName) { + await this.adapter.ensureUniqueness('_Role', requiredRoleFields, ['name']).catch(error => { + logger.warn('Unable to ensure uniqueness for role name: ', error); throw error; }); - - await this.adapter.ensureUniqueness('_Role', requiredRoleFields, ['name']).catch(error => { - logger.warn('Unable to ensure uniqueness for role name: ', error); - throw error; - }); + } await this.adapter .ensureUniqueness('_Idempotency', requiredIdempotencyFields, ['reqId']) diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js index eef946302d..eb05179dd7 100644 --- a/src/Options/Definitions.js +++ b/src/Options/Definitions.js @@ -1104,28 +1104,49 @@ module.exports.DatabaseOptions = { createIndexEmail: { env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_EMAIL', help: - 'Set to `true` to automatically create indexes on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index.', + 'Set to `true` to automatically create indexes on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server.', + action: parsers.booleanParser, + default: true, + }, + createIndexEmailCaseInsensitive: { + env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_EMAIL_CASE_INSENSITIVE', + help: + 'Set to `true` to automatically create a case-insensitive index on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server.', action: parsers.booleanParser, default: true, }, createIndexEmailVerifyToken: { env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_EMAIL_VERIFY_TOKEN', help: - 'Set to `true` to automatically create an index on the _email_verify_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index.', + 'Set to `true` to automatically create an index on the _email_verify_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server.', action: parsers.booleanParser, default: true, }, createIndexPasswordResetToken: { env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_PASSWORD_RESET_TOKEN', help: - 'Set to `true` to automatically create an index on the _perishable_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index.', + 'Set to `true` to automatically create an index on the _perishable_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server.', + action: parsers.booleanParser, + default: true, + }, + createIndexRoleName: { + env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_ROLE_NAME', + help: + 'Set to `true` to automatically create a unique index on the name field of the _Role collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server.', action: parsers.booleanParser, default: true, }, createIndexUsername: { env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_USERNAME', help: - 'Set to `true` to automatically create indexes on the username field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index.', + 'Set to `true` to automatically create indexes on the username field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server.', + action: parsers.booleanParser, + default: true, + }, + createIndexUsernameCaseInsensitive: { + env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_USERNAME_CASE_INSENSITIVE', + help: + 'Set to `true` to automatically create a case-insensitive index on the username field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server.', action: parsers.booleanParser, default: true, }, diff --git a/src/Options/docs.js b/src/Options/docs.js index 9826f36fa9..29e4d60efc 100644 --- a/src/Options/docs.js +++ b/src/Options/docs.js @@ -243,10 +243,13 @@ * @property {Boolean} autoSelectFamily The MongoDB driver option to set whether the socket attempts to connect to IPv6 and IPv4 addresses until a connection is established. If available, the driver will select the first IPv6 address. * @property {Number} autoSelectFamilyAttemptTimeout The MongoDB driver option to specify the amount of time in milliseconds to wait for a connection attempt to finish before trying the next address when using the autoSelectFamily option. If set to a positive integer less than 10, the value 10 is used instead. * @property {Number} connectTimeoutMS The MongoDB driver option to specify the amount of time, in milliseconds, to wait to establish a single TCP socket connection to the server before raising an error. Specifying 0 disables the connection timeout. - * @property {Boolean} createIndexEmail Set to `true` to automatically create indexes on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index. - * @property {Boolean} createIndexEmailVerifyToken Set to `true` to automatically create an index on the _email_verify_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index. - * @property {Boolean} createIndexPasswordResetToken Set to `true` to automatically create an index on the _perishable_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index. - * @property {Boolean} createIndexUsername Set to `true` to automatically create indexes on the username field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index. + * @property {Boolean} createIndexEmail Set to `true` to automatically create indexes on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. + * @property {Boolean} createIndexEmailCaseInsensitive Set to `true` to automatically create a case-insensitive index on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. + * @property {Boolean} createIndexEmailVerifyToken Set to `true` to automatically create an index on the _email_verify_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. + * @property {Boolean} createIndexPasswordResetToken Set to `true` to automatically create an index on the _perishable_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. + * @property {Boolean} createIndexRoleName Set to `true` to automatically create a unique index on the name field of the _Role collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. + * @property {Boolean} createIndexUsername Set to `true` to automatically create indexes on the username field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. + * @property {Boolean} createIndexUsernameCaseInsensitive Set to `true` to automatically create a case-insensitive index on the username field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. * @property {Boolean} disableIndexFieldValidation Set to `true` to disable validation of index fields. When disabled, indexes can be created even if the fields do not exist in the schema. This can be useful when creating indexes on fields that will be added later. * @property {Boolean} enableSchemaHooks Enables database real-time hooks to update single schema cache. Set to `true` if using multiple Parse Servers instances connected to the same database. Failing to do so will cause a schema change to not propagate to all instances and re-syncing will only happen when the instances restart. To use this feature with MongoDB, a replica set cluster with [change stream](https://docs.mongodb.com/manual/changeStreams/#availability) support is required. * @property {Number} maxPoolSize The MongoDB driver option to set the maximum number of opened, cached, ready-to-use database connections maintained by the driver. diff --git a/src/Options/index.js b/src/Options/index.js index 2f6ad11dff..e08f68ebb9 100644 --- a/src/Options/index.js +++ b/src/Options/index.js @@ -632,18 +632,27 @@ export interface DatabaseOptions { autoSelectFamily: ?boolean; /* The MongoDB driver option to specify the amount of time in milliseconds to wait for a connection attempt to finish before trying the next address when using the autoSelectFamily option. If set to a positive integer less than 10, the value 10 is used instead. */ autoSelectFamilyAttemptTimeout: ?number; - /* Set to `true` to automatically create indexes on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index. + /* Set to `true` to automatically create indexes on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. :DEFAULT: true */ createIndexEmail: ?boolean; - /* Set to `true` to automatically create an index on the _email_verify_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index. + /* Set to `true` to automatically create a case-insensitive index on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. + :DEFAULT: true */ + createIndexEmailCaseInsensitive: ?boolean; + /* Set to `true` to automatically create an index on the _email_verify_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. :DEFAULT: true */ createIndexEmailVerifyToken: ?boolean; - /* Set to `true` to automatically create an index on the _perishable_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index. + /* Set to `true` to automatically create an index on the _perishable_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. :DEFAULT: true */ createIndexPasswordResetToken: ?boolean; - /* Set to `true` to automatically create indexes on the username field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ The automatically created index may change in the future to be optimized for the internal usage by Parse Server. Keep this in mind when manually creating this index. + /* Set to `true` to automatically create indexes on the username field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. :DEFAULT: true */ createIndexUsername: ?boolean; + /* Set to `true` to automatically create a case-insensitive index on the username field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. + :DEFAULT: true */ + createIndexUsernameCaseInsensitive: ?boolean; + /* Set to `true` to automatically create a unique index on the name field of the _Role collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. + :DEFAULT: true */ + createIndexRoleName: ?boolean; /* Set to `true` to disable validation of index fields. When disabled, indexes can be created even if the fields do not exist in the schema. This can be useful when creating indexes on fields that will be added later. */ disableIndexFieldValidation: ?boolean; } From 2ce09f32f2715895a79ce008052f2094b2a7a862 Mon Sep 17 00:00:00 2001 From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com> Date: Sat, 1 Nov 2025 16:50:29 +0100 Subject: [PATCH 3/5] tests --- spec/MongoStorageAdapter.spec.js | 155 +++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) diff --git a/spec/MongoStorageAdapter.spec.js b/spec/MongoStorageAdapter.spec.js index b026fc0961..53b74b5f0b 100644 --- a/spec/MongoStorageAdapter.spec.js +++ b/spec/MongoStorageAdapter.spec.js @@ -649,4 +649,159 @@ describe_only_db('mongo')('MongoStorageAdapter', () => { }); }); } + + describe('index creation options', () => { + beforeEach(async () => { + await new MongoStorageAdapter({ uri: databaseURI }).deleteAllClasses(); + }); + + async function getIndexes(collectionName) { + const adapter = Config.get(Parse.applicationId).database.adapter; + const collections = await adapter.database.listCollections({ name: collectionName }).toArray(); + if (collections.length === 0) { + return []; + } + return await adapter.database.collection(collectionName).indexes(); + } + + it('should skip username index when createIndexUsername is false', async () => { + await reconfigureServer({ + databaseAdapter: undefined, + databaseURI, + databaseOptions: { createIndexUsername: false }, + }); + const indexes = await getIndexes('_User'); + expect(indexes.find(idx => idx.name === 'username_1')).toBeUndefined(); + }); + + it('should create username index when createIndexUsername is true', async () => { + await reconfigureServer({ + databaseAdapter: undefined, + databaseURI, + databaseOptions: { createIndexUsername: true }, + }); + const indexes = await getIndexes('_User'); + expect(indexes.find(idx => idx.name === 'username_1')).toBeDefined(); + }); + + it('should skip case-insensitive username index when createIndexUsernameCaseInsensitive is false', async () => { + await reconfigureServer({ + databaseAdapter: undefined, + databaseURI, + databaseOptions: { createIndexUsernameCaseInsensitive: false }, + }); + const indexes = await getIndexes('_User'); + expect(indexes.find(idx => idx.name === 'case_insensitive_username')).toBeUndefined(); + }); + + it('should create case-insensitive username index when createIndexUsernameCaseInsensitive is true', async () => { + await reconfigureServer({ + databaseAdapter: undefined, + databaseURI, + databaseOptions: { createIndexUsernameCaseInsensitive: true }, + }); + const indexes = await getIndexes('_User'); + expect(indexes.find(idx => idx.name === 'case_insensitive_username')).toBeDefined(); + }); + + it('should skip email index when createIndexEmail is false', async () => { + await reconfigureServer({ + databaseAdapter: undefined, + databaseURI, + databaseOptions: { createIndexEmail: false }, + }); + const indexes = await getIndexes('_User'); + expect(indexes.find(idx => idx.name === 'email_1')).toBeUndefined(); + }); + + it('should create email index when createIndexEmail is true', async () => { + await reconfigureServer({ + databaseAdapter: undefined, + databaseURI, + databaseOptions: { createIndexEmail: true }, + }); + const indexes = await getIndexes('_User'); + expect(indexes.find(idx => idx.name === 'email_1')).toBeDefined(); + }); + + it('should skip case-insensitive email index when createIndexEmailCaseInsensitive is false', async () => { + await reconfigureServer({ + databaseAdapter: undefined, + databaseURI, + databaseOptions: { createIndexEmailCaseInsensitive: false }, + }); + const indexes = await getIndexes('_User'); + expect(indexes.find(idx => idx.name === 'case_insensitive_email')).toBeUndefined(); + }); + + it('should create case-insensitive email index when createIndexEmailCaseInsensitive is true', async () => { + await reconfigureServer({ + databaseAdapter: undefined, + databaseURI, + databaseOptions: { createIndexEmailCaseInsensitive: true }, + }); + const indexes = await getIndexes('_User'); + expect(indexes.find(idx => idx.name === 'case_insensitive_email')).toBeDefined(); + }); + + it('should skip email verify token index when createIndexEmailVerifyToken is false', async () => { + await reconfigureServer({ + databaseAdapter: undefined, + databaseURI, + databaseOptions: { createIndexEmailVerifyToken: false }, + }); + const indexes = await getIndexes('_User'); + expect(indexes.find(idx => idx.name === '_email_verify_token' || idx.name === '_email_verify_token_1')).toBeUndefined(); + }); + + it('should create email verify token index when createIndexEmailVerifyToken is true', async () => { + await reconfigureServer({ + databaseAdapter: undefined, + databaseURI, + databaseOptions: { createIndexEmailVerifyToken: true }, + }); + const indexes = await getIndexes('_User'); + expect(indexes.find(idx => idx.name === '_email_verify_token' || idx.name === '_email_verify_token_1')).toBeDefined(); + }); + + it('should skip password reset token index when createIndexPasswordResetToken is false', async () => { + await reconfigureServer({ + databaseAdapter: undefined, + databaseURI, + databaseOptions: { createIndexPasswordResetToken: false }, + }); + const indexes = await getIndexes('_User'); + expect(indexes.find(idx => idx.name === '_perishable_token' || idx.name === '_perishable_token_1')).toBeUndefined(); + }); + + it('should create password reset token index when createIndexPasswordResetToken is true', async () => { + await reconfigureServer({ + databaseAdapter: undefined, + databaseURI, + databaseOptions: { createIndexPasswordResetToken: true }, + }); + const indexes = await getIndexes('_User'); + expect(indexes.find(idx => idx.name === '_perishable_token' || idx.name === '_perishable_token_1')).toBeDefined(); + }); + + it('should skip role name index when createIndexRoleName is false', async () => { + await reconfigureServer({ + databaseAdapter: undefined, + databaseURI, + databaseOptions: { createIndexRoleName: false }, + }); + const indexes = await getIndexes('_Role'); + expect(indexes.find(idx => idx.name === 'name_1')).toBeUndefined(); + }); + + it('should create role name index when createIndexRoleName is true', async () => { + await reconfigureServer({ + databaseAdapter: undefined, + databaseURI, + databaseOptions: { createIndexRoleName: true }, + }); + const indexes = await getIndexes('_Role'); + expect(indexes.find(idx => idx.name === 'name_1')).toBeDefined(); + }); + }); }); From ff87e1e734d5b8b4beaa325098c564cf23d78c14 Mon Sep 17 00:00:00 2001 From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com> Date: Sat, 1 Nov 2025 17:03:30 +0100 Subject: [PATCH 4/5] improvements --- src/Controllers/DatabaseController.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Controllers/DatabaseController.js b/src/Controllers/DatabaseController.js index 8fabd17372..cf40708335 100644 --- a/src/Controllers/DatabaseController.js +++ b/src/Controllers/DatabaseController.js @@ -1740,7 +1740,7 @@ class DatabaseController { const databaseOptions = this.options.databaseOptions || {}; - if (databaseOptions.createIndexUsername) { + if (databaseOptions.createIndexUsername !== false) { await this.adapter.ensureUniqueness('_User', requiredUserFields, ['username']).catch(error => { logger.warn('Unable to ensure uniqueness for usernames: ', error); throw error; @@ -1748,7 +1748,7 @@ class DatabaseController { } if (!this.options.enableCollationCaseComparison) { - if (databaseOptions.createIndexUsernameCaseInsensitive) { + if (databaseOptions.createIndexUsernameCaseInsensitive !== false) { await this.adapter .ensureIndex('_User', requiredUserFields, ['username'], 'case_insensitive_username', true) .catch(error => { @@ -1757,7 +1757,7 @@ class DatabaseController { }); } - if (databaseOptions.createIndexEmailCaseInsensitive) { + if (databaseOptions.createIndexEmailCaseInsensitive !== false) { await this.adapter .ensureIndex('_User', requiredUserFields, ['email'], 'case_insensitive_email', true) .catch(error => { @@ -1767,14 +1767,14 @@ class DatabaseController { } } - if (databaseOptions.createIndexEmail) { + if (databaseOptions.createIndexEmail !== false) { await this.adapter.ensureUniqueness('_User', requiredUserFields, ['email']).catch(error => { logger.warn('Unable to ensure uniqueness for user email addresses: ', error); throw error; }); } - if (databaseOptions.createIndexEmailVerifyToken) { + if (databaseOptions.createIndexEmailVerifyToken !== false) { await this.adapter .ensureIndex('_User', requiredUserFields, ['_email_verify_token'], '_email_verify_token', false) .catch(error => { @@ -1783,7 +1783,7 @@ class DatabaseController { }); } - if (databaseOptions.createIndexPasswordResetToken) { + if (databaseOptions.createIndexPasswordResetToken !== false) { await this.adapter .ensureIndex('_User', requiredUserFields, ['_perishable_token'], '_perishable_token', false) .catch(error => { @@ -1792,7 +1792,7 @@ class DatabaseController { }); } - if (databaseOptions.createIndexRoleName) { + if (databaseOptions.createIndexRoleName !== false) { await this.adapter.ensureUniqueness('_Role', requiredRoleFields, ['name']).catch(error => { logger.warn('Unable to ensure uniqueness for role name: ', error); throw error; From 157516595b1257f95cc4fbb6a6a427bbb2f56493 Mon Sep 17 00:00:00 2001 From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com> Date: Sat, 1 Nov 2025 17:35:41 +0100 Subject: [PATCH 5/5] add class to index option --- spec/MongoStorageAdapter.spec.js | 68 ++++++++++++------- .../Storage/Mongo/MongoStorageAdapter.js | 12 ++-- src/Controllers/DatabaseController.js | 12 ++-- src/Options/Definitions.js | 38 +++++------ src/Options/docs.js | 12 ++-- src/Options/index.js | 12 ++-- 6 files changed, 87 insertions(+), 67 deletions(-) diff --git a/spec/MongoStorageAdapter.spec.js b/spec/MongoStorageAdapter.spec.js index 53b74b5f0b..7d0d220cff 100644 --- a/spec/MongoStorageAdapter.spec.js +++ b/spec/MongoStorageAdapter.spec.js @@ -664,121 +664,121 @@ describe_only_db('mongo')('MongoStorageAdapter', () => { return await adapter.database.collection(collectionName).indexes(); } - it('should skip username index when createIndexUsername is false', async () => { + it('should skip username index when createIndexUserUsername is false', async () => { await reconfigureServer({ databaseAdapter: undefined, databaseURI, - databaseOptions: { createIndexUsername: false }, + databaseOptions: { createIndexUserUsername: false }, }); const indexes = await getIndexes('_User'); expect(indexes.find(idx => idx.name === 'username_1')).toBeUndefined(); }); - it('should create username index when createIndexUsername is true', async () => { + it('should create username index when createIndexUserUsername is true', async () => { await reconfigureServer({ databaseAdapter: undefined, databaseURI, - databaseOptions: { createIndexUsername: true }, + databaseOptions: { createIndexUserUsername: true }, }); const indexes = await getIndexes('_User'); expect(indexes.find(idx => idx.name === 'username_1')).toBeDefined(); }); - it('should skip case-insensitive username index when createIndexUsernameCaseInsensitive is false', async () => { + it('should skip case-insensitive username index when createIndexUserUsernameCaseInsensitive is false', async () => { await reconfigureServer({ databaseAdapter: undefined, databaseURI, - databaseOptions: { createIndexUsernameCaseInsensitive: false }, + databaseOptions: { createIndexUserUsernameCaseInsensitive: false }, }); const indexes = await getIndexes('_User'); expect(indexes.find(idx => idx.name === 'case_insensitive_username')).toBeUndefined(); }); - it('should create case-insensitive username index when createIndexUsernameCaseInsensitive is true', async () => { + it('should create case-insensitive username index when createIndexUserUsernameCaseInsensitive is true', async () => { await reconfigureServer({ databaseAdapter: undefined, databaseURI, - databaseOptions: { createIndexUsernameCaseInsensitive: true }, + databaseOptions: { createIndexUserUsernameCaseInsensitive: true }, }); const indexes = await getIndexes('_User'); expect(indexes.find(idx => idx.name === 'case_insensitive_username')).toBeDefined(); }); - it('should skip email index when createIndexEmail is false', async () => { + it('should skip email index when createIndexUserEmail is false', async () => { await reconfigureServer({ databaseAdapter: undefined, databaseURI, - databaseOptions: { createIndexEmail: false }, + databaseOptions: { createIndexUserEmail: false }, }); const indexes = await getIndexes('_User'); expect(indexes.find(idx => idx.name === 'email_1')).toBeUndefined(); }); - it('should create email index when createIndexEmail is true', async () => { + it('should create email index when createIndexUserEmail is true', async () => { await reconfigureServer({ databaseAdapter: undefined, databaseURI, - databaseOptions: { createIndexEmail: true }, + databaseOptions: { createIndexUserEmail: true }, }); const indexes = await getIndexes('_User'); expect(indexes.find(idx => idx.name === 'email_1')).toBeDefined(); }); - it('should skip case-insensitive email index when createIndexEmailCaseInsensitive is false', async () => { + it('should skip case-insensitive email index when createIndexUserEmailCaseInsensitive is false', async () => { await reconfigureServer({ databaseAdapter: undefined, databaseURI, - databaseOptions: { createIndexEmailCaseInsensitive: false }, + databaseOptions: { createIndexUserEmailCaseInsensitive: false }, }); const indexes = await getIndexes('_User'); expect(indexes.find(idx => idx.name === 'case_insensitive_email')).toBeUndefined(); }); - it('should create case-insensitive email index when createIndexEmailCaseInsensitive is true', async () => { + it('should create case-insensitive email index when createIndexUserEmailCaseInsensitive is true', async () => { await reconfigureServer({ databaseAdapter: undefined, databaseURI, - databaseOptions: { createIndexEmailCaseInsensitive: true }, + databaseOptions: { createIndexUserEmailCaseInsensitive: true }, }); const indexes = await getIndexes('_User'); expect(indexes.find(idx => idx.name === 'case_insensitive_email')).toBeDefined(); }); - it('should skip email verify token index when createIndexEmailVerifyToken is false', async () => { + it('should skip email verify token index when createIndexUserEmailVerifyToken is false', async () => { await reconfigureServer({ databaseAdapter: undefined, databaseURI, - databaseOptions: { createIndexEmailVerifyToken: false }, + databaseOptions: { createIndexUserEmailVerifyToken: false }, }); const indexes = await getIndexes('_User'); expect(indexes.find(idx => idx.name === '_email_verify_token' || idx.name === '_email_verify_token_1')).toBeUndefined(); }); - it('should create email verify token index when createIndexEmailVerifyToken is true', async () => { + it('should create email verify token index when createIndexUserEmailVerifyToken is true', async () => { await reconfigureServer({ databaseAdapter: undefined, databaseURI, - databaseOptions: { createIndexEmailVerifyToken: true }, + databaseOptions: { createIndexUserEmailVerifyToken: true }, }); const indexes = await getIndexes('_User'); expect(indexes.find(idx => idx.name === '_email_verify_token' || idx.name === '_email_verify_token_1')).toBeDefined(); }); - it('should skip password reset token index when createIndexPasswordResetToken is false', async () => { + it('should skip password reset token index when createIndexUserPasswordResetToken is false', async () => { await reconfigureServer({ databaseAdapter: undefined, databaseURI, - databaseOptions: { createIndexPasswordResetToken: false }, + databaseOptions: { createIndexUserPasswordResetToken: false }, }); const indexes = await getIndexes('_User'); expect(indexes.find(idx => idx.name === '_perishable_token' || idx.name === '_perishable_token_1')).toBeUndefined(); }); - it('should create password reset token index when createIndexPasswordResetToken is true', async () => { + it('should create password reset token index when createIndexUserPasswordResetToken is true', async () => { await reconfigureServer({ databaseAdapter: undefined, databaseURI, - databaseOptions: { createIndexPasswordResetToken: true }, + databaseOptions: { createIndexUserPasswordResetToken: true }, }); const indexes = await getIndexes('_User'); expect(indexes.find(idx => idx.name === '_perishable_token' || idx.name === '_perishable_token_1')).toBeDefined(); @@ -803,5 +803,25 @@ describe_only_db('mongo')('MongoStorageAdapter', () => { const indexes = await getIndexes('_Role'); expect(indexes.find(idx => idx.name === 'name_1')).toBeDefined(); }); + + it('should create all indexes by default when options are undefined', async () => { + await reconfigureServer({ + databaseAdapter: undefined, + databaseURI, + databaseOptions: {}, + }); + + const userIndexes = await getIndexes('_User'); + const roleIndexes = await getIndexes('_Role'); + + // Verify all indexes are created with default behavior (backward compatibility) + expect(userIndexes.find(idx => idx.name === 'username_1')).toBeDefined(); + expect(userIndexes.find(idx => idx.name === 'case_insensitive_username')).toBeDefined(); + expect(userIndexes.find(idx => idx.name === 'email_1')).toBeDefined(); + expect(userIndexes.find(idx => idx.name === 'case_insensitive_email')).toBeDefined(); + expect(userIndexes.find(idx => idx.name === '_email_verify_token' || idx.name === '_email_verify_token_1')).toBeDefined(); + expect(userIndexes.find(idx => idx.name === '_perishable_token' || idx.name === '_perishable_token_1')).toBeDefined(); + expect(roleIndexes.find(idx => idx.name === 'name_1')).toBeDefined(); + }); }); }); diff --git a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js index 49a96fbf9a..39b335d52e 100644 --- a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -162,12 +162,12 @@ export class MongoStorageAdapter implements StorageAdapter { 'schemaCacheTtl', 'maxTimeMS', 'disableIndexFieldValidation', - 'createIndexUsername', - 'createIndexUsernameCaseInsensitive', - 'createIndexEmail', - 'createIndexEmailCaseInsensitive', - 'createIndexEmailVerifyToken', - 'createIndexPasswordResetToken', + 'createIndexUserUsername', + 'createIndexUserUsernameCaseInsensitive', + 'createIndexUserEmail', + 'createIndexUserEmailCaseInsensitive', + 'createIndexUserEmailVerifyToken', + 'createIndexUserPasswordResetToken', 'createIndexRoleName', ]) { delete this._mongoOptions[key]; diff --git a/src/Controllers/DatabaseController.js b/src/Controllers/DatabaseController.js index cf40708335..f08bface5a 100644 --- a/src/Controllers/DatabaseController.js +++ b/src/Controllers/DatabaseController.js @@ -1740,7 +1740,7 @@ class DatabaseController { const databaseOptions = this.options.databaseOptions || {}; - if (databaseOptions.createIndexUsername !== false) { + if (databaseOptions.createIndexUserUsername !== false) { await this.adapter.ensureUniqueness('_User', requiredUserFields, ['username']).catch(error => { logger.warn('Unable to ensure uniqueness for usernames: ', error); throw error; @@ -1748,7 +1748,7 @@ class DatabaseController { } if (!this.options.enableCollationCaseComparison) { - if (databaseOptions.createIndexUsernameCaseInsensitive !== false) { + if (databaseOptions.createIndexUserUsernameCaseInsensitive !== false) { await this.adapter .ensureIndex('_User', requiredUserFields, ['username'], 'case_insensitive_username', true) .catch(error => { @@ -1757,7 +1757,7 @@ class DatabaseController { }); } - if (databaseOptions.createIndexEmailCaseInsensitive !== false) { + if (databaseOptions.createIndexUserEmailCaseInsensitive !== false) { await this.adapter .ensureIndex('_User', requiredUserFields, ['email'], 'case_insensitive_email', true) .catch(error => { @@ -1767,14 +1767,14 @@ class DatabaseController { } } - if (databaseOptions.createIndexEmail !== false) { + if (databaseOptions.createIndexUserEmail !== false) { await this.adapter.ensureUniqueness('_User', requiredUserFields, ['email']).catch(error => { logger.warn('Unable to ensure uniqueness for user email addresses: ', error); throw error; }); } - if (databaseOptions.createIndexEmailVerifyToken !== false) { + if (databaseOptions.createIndexUserEmailVerifyToken !== false) { await this.adapter .ensureIndex('_User', requiredUserFields, ['_email_verify_token'], '_email_verify_token', false) .catch(error => { @@ -1783,7 +1783,7 @@ class DatabaseController { }); } - if (databaseOptions.createIndexPasswordResetToken !== false) { + if (databaseOptions.createIndexUserPasswordResetToken !== false) { await this.adapter .ensureIndex('_User', requiredUserFields, ['_perishable_token'], '_perishable_token', false) .catch(error => { diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js index eb05179dd7..d2f1e6eef1 100644 --- a/src/Options/Definitions.js +++ b/src/Options/Definitions.js @@ -1101,50 +1101,50 @@ module.exports.DatabaseOptions = { 'The MongoDB driver option to specify the amount of time, in milliseconds, to wait to establish a single TCP socket connection to the server before raising an error. Specifying 0 disables the connection timeout.', action: parsers.numberParser('connectTimeoutMS'), }, - createIndexEmail: { - env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_EMAIL', + createIndexRoleName: { + env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_ROLE_NAME', help: - 'Set to `true` to automatically create indexes on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server.', + 'Set to `true` to automatically create a unique index on the name field of the _Role collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server.', action: parsers.booleanParser, default: true, }, - createIndexEmailCaseInsensitive: { - env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_EMAIL_CASE_INSENSITIVE', + createIndexUserEmail: { + env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_USER_EMAIL', help: - 'Set to `true` to automatically create a case-insensitive index on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server.', + 'Set to `true` to automatically create indexes on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server.', action: parsers.booleanParser, default: true, }, - createIndexEmailVerifyToken: { - env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_EMAIL_VERIFY_TOKEN', + createIndexUserEmailCaseInsensitive: { + env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_USER_EMAIL_CASE_INSENSITIVE', help: - 'Set to `true` to automatically create an index on the _email_verify_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server.', + 'Set to `true` to automatically create a case-insensitive index on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server.', action: parsers.booleanParser, default: true, }, - createIndexPasswordResetToken: { - env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_PASSWORD_RESET_TOKEN', + createIndexUserEmailVerifyToken: { + env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_USER_EMAIL_VERIFY_TOKEN', help: - 'Set to `true` to automatically create an index on the _perishable_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server.', + 'Set to `true` to automatically create an index on the _email_verify_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server.', action: parsers.booleanParser, default: true, }, - createIndexRoleName: { - env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_ROLE_NAME', + createIndexUserPasswordResetToken: { + env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_USER_PASSWORD_RESET_TOKEN', help: - 'Set to `true` to automatically create a unique index on the name field of the _Role collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server.', + 'Set to `true` to automatically create an index on the _perishable_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server.', action: parsers.booleanParser, default: true, }, - createIndexUsername: { - env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_USERNAME', + createIndexUserUsername: { + env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_USER_USERNAME', help: 'Set to `true` to automatically create indexes on the username field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server.', action: parsers.booleanParser, default: true, }, - createIndexUsernameCaseInsensitive: { - env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_USERNAME_CASE_INSENSITIVE', + createIndexUserUsernameCaseInsensitive: { + env: 'PARSE_SERVER_DATABASE_CREATE_INDEX_USER_USERNAME_CASE_INSENSITIVE', help: 'Set to `true` to automatically create a case-insensitive index on the username field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

\u26A0\uFE0F When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server.', action: parsers.booleanParser, diff --git a/src/Options/docs.js b/src/Options/docs.js index 29e4d60efc..9e650b1038 100644 --- a/src/Options/docs.js +++ b/src/Options/docs.js @@ -243,13 +243,13 @@ * @property {Boolean} autoSelectFamily The MongoDB driver option to set whether the socket attempts to connect to IPv6 and IPv4 addresses until a connection is established. If available, the driver will select the first IPv6 address. * @property {Number} autoSelectFamilyAttemptTimeout The MongoDB driver option to specify the amount of time in milliseconds to wait for a connection attempt to finish before trying the next address when using the autoSelectFamily option. If set to a positive integer less than 10, the value 10 is used instead. * @property {Number} connectTimeoutMS The MongoDB driver option to specify the amount of time, in milliseconds, to wait to establish a single TCP socket connection to the server before raising an error. Specifying 0 disables the connection timeout. - * @property {Boolean} createIndexEmail Set to `true` to automatically create indexes on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. - * @property {Boolean} createIndexEmailCaseInsensitive Set to `true` to automatically create a case-insensitive index on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. - * @property {Boolean} createIndexEmailVerifyToken Set to `true` to automatically create an index on the _email_verify_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. - * @property {Boolean} createIndexPasswordResetToken Set to `true` to automatically create an index on the _perishable_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. * @property {Boolean} createIndexRoleName Set to `true` to automatically create a unique index on the name field of the _Role collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. - * @property {Boolean} createIndexUsername Set to `true` to automatically create indexes on the username field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. - * @property {Boolean} createIndexUsernameCaseInsensitive Set to `true` to automatically create a case-insensitive index on the username field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. + * @property {Boolean} createIndexUserEmail Set to `true` to automatically create indexes on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. + * @property {Boolean} createIndexUserEmailCaseInsensitive Set to `true` to automatically create a case-insensitive index on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. + * @property {Boolean} createIndexUserEmailVerifyToken Set to `true` to automatically create an index on the _email_verify_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. + * @property {Boolean} createIndexUserPasswordResetToken Set to `true` to automatically create an index on the _perishable_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. + * @property {Boolean} createIndexUserUsername Set to `true` to automatically create indexes on the username field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. + * @property {Boolean} createIndexUserUsernameCaseInsensitive Set to `true` to automatically create a case-insensitive index on the username field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. * @property {Boolean} disableIndexFieldValidation Set to `true` to disable validation of index fields. When disabled, indexes can be created even if the fields do not exist in the schema. This can be useful when creating indexes on fields that will be added later. * @property {Boolean} enableSchemaHooks Enables database real-time hooks to update single schema cache. Set to `true` if using multiple Parse Servers instances connected to the same database. Failing to do so will cause a schema change to not propagate to all instances and re-syncing will only happen when the instances restart. To use this feature with MongoDB, a replica set cluster with [change stream](https://docs.mongodb.com/manual/changeStreams/#availability) support is required. * @property {Number} maxPoolSize The MongoDB driver option to set the maximum number of opened, cached, ready-to-use database connections maintained by the driver. diff --git a/src/Options/index.js b/src/Options/index.js index e08f68ebb9..42da7b2237 100644 --- a/src/Options/index.js +++ b/src/Options/index.js @@ -634,22 +634,22 @@ export interface DatabaseOptions { autoSelectFamilyAttemptTimeout: ?number; /* Set to `true` to automatically create indexes on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. :DEFAULT: true */ - createIndexEmail: ?boolean; + createIndexUserEmail: ?boolean; /* Set to `true` to automatically create a case-insensitive index on the email field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. :DEFAULT: true */ - createIndexEmailCaseInsensitive: ?boolean; + createIndexUserEmailCaseInsensitive: ?boolean; /* Set to `true` to automatically create an index on the _email_verify_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. :DEFAULT: true */ - createIndexEmailVerifyToken: ?boolean; + createIndexUserEmailVerifyToken: ?boolean; /* Set to `true` to automatically create an index on the _perishable_token field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. :DEFAULT: true */ - createIndexPasswordResetToken: ?boolean; + createIndexUserPasswordResetToken: ?boolean; /* Set to `true` to automatically create indexes on the username field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. :DEFAULT: true */ - createIndexUsername: ?boolean; + createIndexUserUsername: ?boolean; /* Set to `true` to automatically create a case-insensitive index on the username field of the _User collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. :DEFAULT: true */ - createIndexUsernameCaseInsensitive: ?boolean; + createIndexUserUsernameCaseInsensitive: ?boolean; /* Set to `true` to automatically create a unique index on the name field of the _Role collection on server start. Set to `false` to skip index creation. Default is `true`.

⚠️ When setting this option to `false` to manually create the index, keep in mind that the otherwise automatically created index may change in the future to be optimized for the internal usage by Parse Server. :DEFAULT: true */ createIndexRoleName: ?boolean;