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 databaseURI = 'mongodb://localhost:27017/parse';
|
||||||
const gfsAdapter = new GridFSBucketAdapter(databaseURI, {
|
const gfsAdapter = new GridFSBucketAdapter(databaseURI, {
|
||||||
retryWrites: true,
|
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,
|
enableSchemaHooks: true,
|
||||||
schemaCacheTtl: 5000,
|
schemaCacheTtl: 5000,
|
||||||
maxTimeMS: 30000,
|
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();
|
const db = await gfsAdapter._connect();
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
// @flow-disable-next
|
// @flow-disable-next
|
||||||
import { MongoClient, GridFSBucket, Db } from 'mongodb';
|
import { MongoClient, GridFSBucket, Db } from 'mongodb';
|
||||||
import { FilesAdapter, validateFilename } from './FilesAdapter';
|
import { FilesAdapter, validateFilename } from './FilesAdapter';
|
||||||
import defaults from '../../defaults';
|
import defaults, { ParseServerDatabaseOptions } from '../../defaults';
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
|
|
||||||
export class GridFSBucketAdapter extends FilesAdapter {
|
export class GridFSBucketAdapter extends FilesAdapter {
|
||||||
@@ -34,10 +34,10 @@ export class GridFSBucketAdapter extends FilesAdapter {
|
|||||||
.digest('base64')
|
.digest('base64')
|
||||||
.substring(0, 32)
|
.substring(0, 32)
|
||||||
: null;
|
: null;
|
||||||
const defaultMongoOptions = {
|
const defaultMongoOptions = {};
|
||||||
};
|
|
||||||
const _mongoOptions = Object.assign(defaultMongoOptions, mongoOptions);
|
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];
|
delete _mongoOptions[key];
|
||||||
}
|
}
|
||||||
this._mongoOptions = _mongoOptions;
|
this._mongoOptions = _mongoOptions;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
import Parse from 'parse/node';
|
import Parse from 'parse/node';
|
||||||
// @flow-disable-next
|
// @flow-disable-next
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import defaults from '../../../defaults';
|
import defaults, { ParseServerDatabaseOptions } from '../../../defaults';
|
||||||
import logger from '../../../logger';
|
import logger from '../../../logger';
|
||||||
import Utils from '../../../Utils';
|
import Utils from '../../../Utils';
|
||||||
|
|
||||||
@@ -147,7 +147,6 @@ export class MongoStorageAdapter implements StorageAdapter {
|
|||||||
constructor({ uri = defaults.DefaultMongoURI, collectionPrefix = '', mongoOptions = {} }: any) {
|
constructor({ uri = defaults.DefaultMongoURI, collectionPrefix = '', mongoOptions = {} }: any) {
|
||||||
this._uri = uri;
|
this._uri = uri;
|
||||||
this._collectionPrefix = collectionPrefix;
|
this._collectionPrefix = collectionPrefix;
|
||||||
this._mongoOptions = { ...mongoOptions };
|
|
||||||
this._onchange = () => {};
|
this._onchange = () => {};
|
||||||
|
|
||||||
// MaxTimeMS is not a global MongoDB client option, it is applied per operation.
|
// 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.disableIndexFieldValidation = !!mongoOptions.disableIndexFieldValidation;
|
||||||
this._logClientEvents = mongoOptions.logClientEvents;
|
this._logClientEvents = mongoOptions.logClientEvents;
|
||||||
|
|
||||||
// Remove Parse Server-specific options that should not be passed to MongoDB client
|
// Create a copy of mongoOptions and remove Parse Server-specific options that should not
|
||||||
// Note: We only delete from this._mongoOptions, not from the original mongoOptions object,
|
// be passed to MongoDB client. Note: We only delete from this._mongoOptions, not from the
|
||||||
// because other components (like DatabaseController) need access to these options
|
// original mongoOptions object, because other components (like DatabaseController) need
|
||||||
for (const key of [
|
// access to these options.
|
||||||
'allowPublicExplain',
|
this._mongoOptions = { ...mongoOptions };
|
||||||
'enableSchemaHooks',
|
for (const key of ParseServerDatabaseOptions) {
|
||||||
'schemaCacheTtl',
|
|
||||||
'maxTimeMS',
|
|
||||||
'disableIndexFieldValidation',
|
|
||||||
'logClientEvents',
|
|
||||||
'createIndexUserUsername',
|
|
||||||
'createIndexUserUsernameCaseInsensitive',
|
|
||||||
'createIndexUserEmail',
|
|
||||||
'createIndexUserEmailCaseInsensitive',
|
|
||||||
'createIndexUserEmailVerifyToken',
|
|
||||||
'createIndexUserPasswordResetToken',
|
|
||||||
'createIndexRoleName',
|
|
||||||
]) {
|
|
||||||
delete this._mongoOptions[key];
|
delete this._mongoOptions[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,3 +33,21 @@ const computedDefaults = {
|
|||||||
|
|
||||||
export default Object.assign({}, DefinitionDefaults, computedDefaults);
|
export default Object.assign({}, DefinitionDefaults, computedDefaults);
|
||||||
export const DefaultMongoURI = DefinitionDefaults.databaseURI;
|
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',
|
||||||
|
];
|
||||||
|
|||||||
14
types/Options/index.d.ts
vendored
14
types/Options/index.d.ts
vendored
@@ -228,7 +228,19 @@ export interface FileUploadOptions {
|
|||||||
}
|
}
|
||||||
export interface DatabaseOptions {
|
export interface DatabaseOptions {
|
||||||
// Parse Server custom options
|
// Parse Server custom options
|
||||||
|
allowPublicExplain?: boolean;
|
||||||
|
createIndexRoleName?: boolean;
|
||||||
|
createIndexUserEmail?: boolean;
|
||||||
|
createIndexUserEmailCaseInsensitive?: boolean;
|
||||||
|
createIndexUserEmailVerifyToken?: boolean;
|
||||||
|
createIndexUserPasswordResetToken?: boolean;
|
||||||
|
createIndexUserUsername?: boolean;
|
||||||
|
createIndexUserUsernameCaseInsensitive?: boolean;
|
||||||
|
disableIndexFieldValidation?: boolean;
|
||||||
enableSchemaHooks?: 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;
|
schemaCacheTtl?: number;
|
||||||
|
|
||||||
// MongoDB driver options
|
// MongoDB driver options
|
||||||
@@ -238,7 +250,6 @@ export interface DatabaseOptions {
|
|||||||
authSource?: string;
|
authSource?: string;
|
||||||
autoSelectFamily?: boolean;
|
autoSelectFamily?: boolean;
|
||||||
autoSelectFamilyAttemptTimeout?: number;
|
autoSelectFamilyAttemptTimeout?: number;
|
||||||
allowPublicExplain?: boolean;
|
|
||||||
compressors?: string[] | string;
|
compressors?: string[] | string;
|
||||||
connectTimeoutMS?: number;
|
connectTimeoutMS?: number;
|
||||||
directConnection?: boolean;
|
directConnection?: boolean;
|
||||||
@@ -250,7 +261,6 @@ export interface DatabaseOptions {
|
|||||||
maxIdleTimeMS?: number;
|
maxIdleTimeMS?: number;
|
||||||
maxPoolSize?: number;
|
maxPoolSize?: number;
|
||||||
maxStalenessSeconds?: number;
|
maxStalenessSeconds?: number;
|
||||||
maxTimeMS?: number;
|
|
||||||
minPoolSize?: number;
|
minPoolSize?: number;
|
||||||
proxyHost?: string;
|
proxyHost?: string;
|
||||||
proxyPassword?: string;
|
proxyPassword?: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user