Skip to content

Commit c1c7e69

Browse files
authored
feat: Deprecation DEPPS12: Database option allowPublicExplain defaults to false (#9975)
BREAKING CHANGE: This release changes the MongoDB database option `allowPublicExplain` default to `false` (Deprecation DEPPS12).
1 parent a4c8d9e commit c1c7e69

File tree

7 files changed

+17
-22
lines changed

7 files changed

+17
-22
lines changed

DEPRECATIONS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ The following is a list of deprecations, according to the [Deprecation Policy](h
1515
| DEPPS9 | Rename LiveQuery `fields` option to `keys` | [#8389](https://github.com/parse-community/parse-server/issues/8389) | 6.0.0 (2023) | 7.0.0 (2024) | removed | - |
1616
| DEPPS10 | Encode `Parse.Object` in Cloud Function and remove option `encodeParseObjectInCloudFunction` | [#8634](https://github.com/parse-community/parse-server/issues/8634) | 6.2.0 (2023) | 9.0.0 (2026) | removed | - |
1717
| DEPPS11 | Replace `PublicAPIRouter` with `PagesRouter` | [#7625](https://github.com/parse-community/parse-server/issues/7625) | 8.0.0 (2025) | 9.0.0 (2026) | removed | - |
18-
| DEPPS12 | Database option `allowPublicExplain` will default to `true` | [#7519](https://github.com/parse-community/parse-server/issues/7519) | 8.5.0 (2025) | 9.0.0 (2026) | deprecated | - |
18+
| DEPPS12 | Database option `allowPublicExplain` defaults to `false` | [#7519](https://github.com/parse-community/parse-server/issues/7519) | 8.5.0 (2025) | 9.0.0 (2026) | removed | - |
1919

2020
[i_deprecation]: ## "The version and date of the deprecation."
2121
[i_removal]: ## "The version and date of the planned removal."

spec/Deprecator.spec.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ describe('Deprecator', () => {
4747
});
4848

4949
it('logs deprecation for nested option key with dot notation', async () => {
50-
deprecations = [{ optionKey: 'databaseOptions.allowPublicExplain', changeNewDefault: 'false' }];
50+
deprecations = [{ optionKey: 'databaseOptions.testOption', changeNewDefault: 'false' }];
5151

5252
spyOn(Deprecator, '_getDeprecations').and.callFake(() => deprecations);
5353
const logger = require('../lib/logger').logger;
@@ -60,14 +60,14 @@ describe('Deprecator', () => {
6060
});
6161

6262
it('does not log deprecation for nested option key if option is set manually', async () => {
63-
deprecations = [{ optionKey: 'databaseOptions.allowPublicExplain', changeNewDefault: 'false' }];
63+
deprecations = [{ optionKey: 'databaseOptions.testOption', changeNewDefault: 'false' }];
6464

6565
spyOn(Deprecator, '_getDeprecations').and.callFake(() => deprecations);
6666
const logSpy = spyOn(Deprecator, '_logOption').and.callFake(() => {});
6767
const Config = require('../lib/Config');
6868
const config = Config.get('test');
6969
// Directly test scanParseServerOptions with nested option set
70-
Deprecator.scanParseServerOptions({ databaseOptions: { allowPublicExplain: true } });
70+
Deprecator.scanParseServerOptions({ databaseOptions: { testOption: true } });
7171
expect(logSpy).not.toHaveBeenCalled();
7272
});
7373
});

spec/ParseQuery.spec.js

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5369,7 +5369,7 @@ describe('Parse.Query testing', () => {
53695369
const query = new Parse.Query('_User');
53705370
query.equalTo('objectId', user.id);
53715371
query.explain();
5372-
const result = await query.find();
5372+
const result = await query.find({ useMasterKey: true });
53735373
// Validate
53745374
expect(result.executionStats).not.toBeUndefined();
53755375
});
@@ -5533,11 +5533,8 @@ describe('Parse.Query testing', () => {
55335533
);
55345534

55355535
it_id('c3d4e5f6-a7b8-4c9d-0e1f-2a3b4c5d6e7f')(it_only_db('mongo'))(
5536-
'explain works with and without master key by default',
5536+
'explain requires master key by default',
55375537
async () => {
5538-
const logger = require('../lib/logger').logger;
5539-
const logSpy = spyOn(logger, 'warn').and.callFake(() => {});
5540-
55415538
await reconfigureServer({
55425539
databaseAdapter: undefined,
55435540
databaseURI: 'mongodb://localhost:27017/parse',
@@ -5546,21 +5543,20 @@ describe('Parse.Query testing', () => {
55465543
},
55475544
});
55485545

5549-
// Verify deprecation warning is logged when allowPublicExplain is not explicitly set
5550-
expect(logSpy).toHaveBeenCalledWith(
5551-
jasmine.stringMatching(/DeprecationWarning.*databaseOptions\.allowPublicExplain.*false/)
5552-
);
5553-
55545546
const obj = new TestObject({ foo: 'bar' });
55555547
await obj.save();
55565548

5557-
// Without master key
5549+
// Without master key - should fail
55585550
const query = new Parse.Query(TestObject);
55595551
query.explain();
5560-
const resultWithoutMasterKey = await query.find();
5561-
expect(resultWithoutMasterKey).toBeDefined();
5552+
await expectAsync(query.find()).toBeRejectedWith(
5553+
new Parse.Error(
5554+
Parse.Error.INVALID_QUERY,
5555+
'Using the explain query parameter requires the master key'
5556+
)
5557+
);
55625558

5563-
// With master key
5559+
// With master key - should succeed
55645560
const queryWithMasterKey = new Parse.Query(TestObject);
55655561
queryWithMasterKey.explain();
55665562
const resultWithMasterKey = await queryWithMasterKey.find({ useMasterKey: true });

src/Deprecator/Deprecations.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,4 @@
1717
*/
1818
module.exports = [
1919
{ optionKey: 'enableInsecureAuthAdapters', changeNewDefault: 'false' },
20-
{ optionKey: 'databaseOptions.allowPublicExplain', changeNewDefault: 'false' },
2120
];

src/Options/Definitions.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1144,7 +1144,7 @@ module.exports.DatabaseOptions = {
11441144
help:
11451145
'Set to `true` to allow `Parse.Query.explain` without master key.<br><br>\u26A0\uFE0F Enabling this option may expose sensitive query performance data to unauthorized users and could potentially be exploited for malicious purposes.',
11461146
action: parsers.booleanParser,
1147-
default: true,
1147+
default: false,
11481148
},
11491149
appName: {
11501150
env: 'PARSE_SERVER_DATABASE_APP_NAME',

src/Options/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,7 @@ export interface DatabaseOptions {
751751
/* 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. */
752752
disableIndexFieldValidation: ?boolean;
753753
/* Set to `true` to allow `Parse.Query.explain` without master key.<br><br>⚠️ Enabling this option may expose sensitive query performance data to unauthorized users and could potentially be exploited for malicious purposes.
754-
:DEFAULT: true */
754+
:DEFAULT: false */
755755
allowPublicExplain: ?boolean;
756756
/* An array of MongoDB client event configurations to enable logging of specific events. */
757757
logClientEvents: ?(LogClientEvent[]);

src/rest.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ async function runFindTriggers(
3737
const { isGet } = options;
3838

3939
if (restOptions && restOptions.explain && !auth.isMaster) {
40-
const allowPublicExplain = config.databaseOptions?.allowPublicExplain ?? true;
40+
const allowPublicExplain = config.databaseOptions?.allowPublicExplain ?? false;
4141

4242
if (!allowPublicExplain) {
4343
throw new Parse.Error(

0 commit comments

Comments
 (0)