fix: GridFSBucketAdapter throws when using some Parse Server specific options in MongoDB database options (#9915)
This commit is contained in:
@@ -24,10 +24,20 @@ describe_only_db('mongo')('GridFSBucket', () => {
|
||||
const databaseURI = 'mongodb://localhost:27017/parse';
|
||||
const gfsAdapter = new GridFSBucketAdapter(databaseURI, {
|
||||
retryWrites: true,
|
||||
// these are not supported by the mongo client
|
||||
// Parse Server-specific options that should be filtered out before passing to MongoDB client
|
||||
allowPublicExplain: true,
|
||||
enableSchemaHooks: true,
|
||||
schemaCacheTtl: 5000,
|
||||
maxTimeMS: 30000,
|
||||
disableIndexFieldValidation: true,
|
||||
logClientEvents: [{ name: 'commandStarted' }],
|
||||
createIndexUserUsername: true,
|
||||
createIndexUserUsernameCaseInsensitive: true,
|
||||
createIndexUserEmail: true,
|
||||
createIndexUserEmailCaseInsensitive: true,
|
||||
createIndexUserEmailVerifyToken: true,
|
||||
createIndexUserPasswordResetToken: true,
|
||||
createIndexRoleName: true,
|
||||
});
|
||||
|
||||
const db = await gfsAdapter._connect();
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
// @flow-disable-next
|
||||
import { MongoClient, GridFSBucket, Db } from 'mongodb';
|
||||
import { FilesAdapter, validateFilename } from './FilesAdapter';
|
||||
import defaults from '../../defaults';
|
||||
import defaults, { ParseServerDatabaseOptions } from '../../defaults';
|
||||
const crypto = require('crypto');
|
||||
|
||||
export class GridFSBucketAdapter extends FilesAdapter {
|
||||
@@ -34,10 +34,10 @@ export class GridFSBucketAdapter extends FilesAdapter {
|
||||
.digest('base64')
|
||||
.substring(0, 32)
|
||||
: null;
|
||||
const defaultMongoOptions = {
|
||||
};
|
||||
const defaultMongoOptions = {};
|
||||
const _mongoOptions = Object.assign(defaultMongoOptions, mongoOptions);
|
||||
for (const key of ['enableSchemaHooks', 'schemaCacheTtl', 'maxTimeMS', 'disableIndexFieldValidation']) {
|
||||
// Remove Parse Server-specific options that should not be passed to MongoDB client
|
||||
for (const key of ParseServerDatabaseOptions) {
|
||||
delete _mongoOptions[key];
|
||||
}
|
||||
this._mongoOptions = _mongoOptions;
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
import Parse from 'parse/node';
|
||||
// @flow-disable-next
|
||||
import _ from 'lodash';
|
||||
import defaults from '../../../defaults';
|
||||
import defaults, { ParseServerDatabaseOptions } from '../../../defaults';
|
||||
import logger from '../../../logger';
|
||||
import Utils from '../../../Utils';
|
||||
|
||||
@@ -147,7 +147,6 @@ export class MongoStorageAdapter implements StorageAdapter {
|
||||
constructor({ uri = defaults.DefaultMongoURI, collectionPrefix = '', mongoOptions = {} }: any) {
|
||||
this._uri = uri;
|
||||
this._collectionPrefix = collectionPrefix;
|
||||
this._mongoOptions = { ...mongoOptions };
|
||||
this._onchange = () => {};
|
||||
|
||||
// MaxTimeMS is not a global MongoDB client option, it is applied per operation.
|
||||
@@ -158,24 +157,12 @@ export class MongoStorageAdapter implements StorageAdapter {
|
||||
this.disableIndexFieldValidation = !!mongoOptions.disableIndexFieldValidation;
|
||||
this._logClientEvents = mongoOptions.logClientEvents;
|
||||
|
||||
// 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 [
|
||||
'allowPublicExplain',
|
||||
'enableSchemaHooks',
|
||||
'schemaCacheTtl',
|
||||
'maxTimeMS',
|
||||
'disableIndexFieldValidation',
|
||||
'logClientEvents',
|
||||
'createIndexUserUsername',
|
||||
'createIndexUserUsernameCaseInsensitive',
|
||||
'createIndexUserEmail',
|
||||
'createIndexUserEmailCaseInsensitive',
|
||||
'createIndexUserEmailVerifyToken',
|
||||
'createIndexUserPasswordResetToken',
|
||||
'createIndexRoleName',
|
||||
]) {
|
||||
// Create a copy of mongoOptions and 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.
|
||||
this._mongoOptions = { ...mongoOptions };
|
||||
for (const key of ParseServerDatabaseOptions) {
|
||||
delete this._mongoOptions[key];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,3 +33,21 @@ const computedDefaults = {
|
||||
|
||||
export default Object.assign({}, DefinitionDefaults, computedDefaults);
|
||||
export const DefaultMongoURI = DefinitionDefaults.databaseURI;
|
||||
|
||||
// Parse Server-specific database options that should be filtered out
|
||||
// before passing to MongoDB client
|
||||
export const ParseServerDatabaseOptions = [
|
||||
'allowPublicExplain',
|
||||
'createIndexRoleName',
|
||||
'createIndexUserEmail',
|
||||
'createIndexUserEmailCaseInsensitive',
|
||||
'createIndexUserEmailVerifyToken',
|
||||
'createIndexUserPasswordResetToken',
|
||||
'createIndexUserUsername',
|
||||
'createIndexUserUsernameCaseInsensitive',
|
||||
'disableIndexFieldValidation',
|
||||
'enableSchemaHooks',
|
||||
'logClientEvents',
|
||||
'maxTimeMS',
|
||||
'schemaCacheTtl',
|
||||
];
|
||||
|
||||
16
types/Options/index.d.ts
vendored
16
types/Options/index.d.ts
vendored
@@ -228,9 +228,21 @@ export interface FileUploadOptions {
|
||||
}
|
||||
export interface DatabaseOptions {
|
||||
// Parse Server custom options
|
||||
allowPublicExplain?: boolean;
|
||||
createIndexRoleName?: boolean;
|
||||
createIndexUserEmail?: boolean;
|
||||
createIndexUserEmailCaseInsensitive?: boolean;
|
||||
createIndexUserEmailVerifyToken?: boolean;
|
||||
createIndexUserPasswordResetToken?: boolean;
|
||||
createIndexUserUsername?: boolean;
|
||||
createIndexUserUsernameCaseInsensitive?: boolean;
|
||||
disableIndexFieldValidation?: boolean;
|
||||
enableSchemaHooks?: boolean;
|
||||
logClientEvents?: any[];
|
||||
// maxTimeMS is a MongoDB option but Parse Server applies it per-operation, not as a global client option
|
||||
maxTimeMS?: number;
|
||||
schemaCacheTtl?: number;
|
||||
|
||||
|
||||
// MongoDB driver options
|
||||
appName?: string;
|
||||
authMechanism?: string;
|
||||
@@ -238,7 +250,6 @@ export interface DatabaseOptions {
|
||||
authSource?: string;
|
||||
autoSelectFamily?: boolean;
|
||||
autoSelectFamilyAttemptTimeout?: number;
|
||||
allowPublicExplain?: boolean;
|
||||
compressors?: string[] | string;
|
||||
connectTimeoutMS?: number;
|
||||
directConnection?: boolean;
|
||||
@@ -250,7 +261,6 @@ export interface DatabaseOptions {
|
||||
maxIdleTimeMS?: number;
|
||||
maxPoolSize?: number;
|
||||
maxStalenessSeconds?: number;
|
||||
maxTimeMS?: number;
|
||||
minPoolSize?: number;
|
||||
proxyHost?: string;
|
||||
proxyPassword?: string;
|
||||
|
||||
Reference in New Issue
Block a user